浅析无回显的XXE(BlindXXE)

如题所述

第1个回答  2024-09-04
xml介绍

XML是一种非常流行的标记语言,在解析外部实体的过程中,XML解析器可以根据URL中指定的方案(协议)来查询各种网络协议和服务(DNS,FTP,HTTP,SMB等)。外部实体对于在文档中创建动态引用非常有用,这样对引用资源所做的任何更改都会在文档中自动更新。但是,在处理外部实体时,可以针对应用程序启动许多攻击。这些攻击包括泄露本地系统文件,这些文件可能包含密码和私人用户数据等敏感数据,或利用各种方案的网络访问功能来操纵内部应用程序。通过将这些攻击与其他实现缺陷相结合,这些攻击的范围可以扩展到客户端内存损坏,任意代码执行,甚至服务中断,具体取决于这些攻击的上下文。

内部实体

XML文档有自己的一个格式规范,这个格式规范是由一个叫做DTD(documenttypedefinition)的东西控制的。

<?xmlversion="1.0"?>//这一行是XML文档定义<!DOCTYPEmessage[<!ELEMENTmessage(receiver,sender,header,msg)><!ELEMENTreceiver(#PCDATA)><!ELEMENTsender(#PCDATA)><!ELEMENTheader(#PCDATA)><!ELEMENTmsg(#PCDATA)>

上面这个DTD就定义了XML的根元素是message,然后跟元素下面有一些子元素,那么XML到时候必须像下面这么写

<message><receiver>Myself</receiver><sender>Someone</sender><header>TheReminder</header><msg>Thisisanamazingbook</msg></message>

其实除了在DTD中定义元素(其实就是对应XML中的标签)以外,我们还能在DTD中定义实体(对应XML标签中的内容),毕竟XML中除了能标签以外,还需要有些内容是固定的

<?xmlversion="1.0"encoding="ISO-8859-1"?><!DOCTYPEfoo[<!ELEMENTfooANY><!ENTITYxxe"test">]>

这里定义元素为ANY说明接受任何元素,但是定义了一个xml的实体(实体其实可以看成一个变量,到时候我们可以在XML中通过&符号进行引用),那么XML就可以写成这样

示例代码:

<creds><user>&xxe;</user><pass>mypass</pass></creds>

我们使用&xxe对上面定义的xxe实体进行了引用,到时候输出的时候&xxe就会被"test"替换。

外部实体

示例代码:

<?xmlversion="1.0"encoding="ISO-8859-1"?><!DOCTYPEfoo[<!ELEMENTfooANY><!ENTITYxxeSYSTEM"file:///c:/test.dtd">]><creds><user>&xxe;</user><pass>mypass</pass></creds>

当然,还有一种引用方式是使用引用公用DTD的方法,语法如下:

<!DOCTYPE根元素名称PUBLIC“DTD标识名”“公用DTD的URI”>

我们上面已经将实体分成了两个派别(内部实体和外部外部),但是实际上从另一个角度看,实体也可以分成两个派别(通用实体和参数实体)。

通用实体

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

<?xmlversion="1.0"encoding="utf-8"?><!DOCTYPEupdateProfile[<!ENTITYfileSYSTEM"file:///c:/windows/win.ini">]><updateProfile><firstname>Joe</firstname><lastname>&file;</lastname>...</updateProfile>

参数实体

(1)使用%实体名(这里面空格不能少)在DTD中定义,并且只能在DTD中使用%实体名;引用(2)只有在DTD文件中,参数实体的声明才能引用其他实体(3)和通用实体一样,参数实体也可以外部引用

示例代码:

<!ENTITY%an-element"<!ELEMENTmytag(subtag)>"><!ENTITY%remote-dtdSYSTEM"http://somewhere.example.org/remote.dtd">%an-element;%remote-dtd;

抛转:参数实体在我们BlindXXE中起到了至关重要的作用

有回显XXE

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

本地服务器上放上解析XML的php代码:

xml.php

<?phplibxml_disable_entity_loader(false);$xmlfile=file_get_contents('php://input');$dom=newDOMDocument();$dom->loadXML($xmlfile,LIBXML_NOENT|LIBXML_DTDLOAD);$creds=simplexml_import_dom($dom);echo$creds;?>

其中:LIBXML_NOENT:将XML中的实体引用替换成对应的值LIBXML_DTDLOAD:加载DOCTYPE中的DTD文件

触发xxe

<!DOCTYPEfoo[<!ELEMENTfooANY><!ENTITYxxe"Helloworld!">]>

?

读取本地服务器C盘的flag文件

<message><receiver>Myself</receiver><sender>Someone</sender><header>TheReminder</header><msg>Thisisanamazingbook</msg></message>0

?

引用外部实体读取文件

?

引用方式是使用引用公用DTD的方法读取

?

无回显XXE

有回显的情况可以直接在页面中看到Payload的执行结果或现象,无回显的情况又称为blindxxe,可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器。

xml.php

<message><receiver>Myself</receiver><sender>Someone</sender><header>TheReminder</header><msg>Thisisanamazingbook</msg></message>1

test.dtd

<message><receiver>Myself</receiver><sender>Someone</sender><header>TheReminder</header><msg>Thisisanamazingbook</msg></message>2

payload

<message><receiver>Myself</receiver><sender>Someone</sender><header>TheReminder</header><msg>Thisisanamazingbook</msg></message>3

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

?

?

这样,我们就读到了flag文件的内容。

参考文章

https://xz.aliyun.com/t/3357#toc-10一篇文章带你深入理解漏洞之XXE漏洞

实验推荐

实验:第十四周|blindxxe(合天网安实验室)点击进入实操>>

更多靶场实验练习、网安学习资料,请点击这里>>

原文:https://juejin.cn/post/7096382411621023752

logo设计

创造品牌价值

¥500元起

APP开发

量身定制,源码交付

¥2000元起

商标注册

一个好品牌从商标开始

¥1480元起

公司注册

注册公司全程代办

¥0元起

    官方电话官方服务
      官方网站八戒财税知识产权八戒服务商企业需求数字市场

相关了解……

你可能感兴趣的内容

大家正在搜

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网