XXE漏洞全称是XML External Entity Injection,即XML外部实体注入漏洞,当XML允许引用外部实体并解析时,攻击者就可以构造恶意实体的payload进行注入攻击,造成文件读取、命令执行、攻击内网网站及SSRF等危害。
XML全称是可扩展标记语言(EXtensible Markup Language),它的格式与HTML很像,通常被用来传输和存储数据,XML的标签没有被预定义,所以我们需要自行定义标签。
DTD全称是文档类型定义(Document Type Definition),是一套关于标记符的语法规则。它可被成行地声明于 XML 文档中,也可作为一个外部引用。
]>
小星
18
三好学生
XML的一般格式:
1、XML声明:
2、定义文档内部或者引用外部实体格式:
(1)内部DTD文档:
(2)外部DTD文档:
3、引用实体:&实体名称
什么情况下会出现XXE漏洞呢?我们看下面这段代码:
]>
&xxe;
这段代码引用了一个外部实体,变量名为xxe,值为:file:///etc/passwd,然后用&xxe引用实体。当我们构造恶意实体的payload,对引用实体路径进行注入攻击时,就造成了xxe攻击。
进行XXE漏洞测试时,除了一些XML的基础外,还需要了解不同的协议,PHP支持的协议有:
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
任意文件读取
index.php
LoadXML($xmlfile, LIBXML_BIGLINES | LIBXML_NOWARNING | LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom ($dom);
echo $creds;
?>
index.php需要接收一个POST请求才能执行,我们把以下XML代码POST过去就可以实现任意文件读取:
]>
&xxe;
实例:
靶场环境:xxe-lab
源码下载链接:https://codeload.github.com/c0ny1/xxe-lab/zip/master
进入靶场,发现这是一个登陆界面
用burpsuite抓包发现,数据是利用XML进行传输的
从上图可以看出响应包中显示的内容为username的值,然后我们就可以构造payload,最后输出在username里就可以了
payload:
]>
&xxe; 123
这种是有回显的xxe注入。
接下来我们尝试一下无回显的情况,修改源代码,添加error_reporting(0);
禁止报错,并注释输出。
再次尝试注入就不会返回结果
这时我们就需要进行参数实体注入
构造payload:
%dtd;
%send;
]>
%表示参数实体,% file表示定义一个名为file的参数实体,然后再SYSTEM引用外部实体内容'php://filter/read=convert.base64-encode/resource=D:/phpStudy/PHPTutorial/WWW/xxe-lab/php_xxe/doLogin.php'
这里我们还需要kail,开启kali的apache2服务,然后在/var/www/html目录下新建文件evil.dtd,内容为:
">
%payload;
然后我们开始监控apache的访问日志,在终端输入:
然后发送请求,执行payload
浏览器上还是没有显示结果,不过这时再查看监控的日志文件,发现已经得到了doLogin.php的源码
命令执行
]>
&xxe;
**注意:**这种情况下得安装Expect拓展才能,而默认情况下expect是没有安装的。
内网探测/SSRF
由于xml实体注入攻击可以利用http://协议,也就是可以发起http请求。可以利用该请求去探查内网,进行SSRF攻击。
还用刚才的xxe-labs来演示,payload如下:
]>
&xxe; 1
这里虽然有些地方是乱码的,不过可以看出81端口是没有开放的,我们再对比一下80端口的返回结果
虽然80端口也有一点报错信息,但经过对比可以明显看出80端口是开放的。
DDoS拒绝服务攻击
示例代码:
]>
&xxe9;
该攻击原理为:构造恶意的XML实体文件耗尽可用内存,由于许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,就会导致解析非常慢,从而造成了拒绝服务器攻击。
1、使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
.setFeature("http://xml.org/sax/features/external-general-entities",false)
.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2、过滤用户提交的XML数据
过滤关键词:
通过总结,让我对XXE漏洞有了一个全新的认识,这其中也花了很长时间,特别是测试的过程,有些地方网上描述的不是很清楚,所以自己花了很长时间来查资料和实践,不过还好,多花点时间在学习上总比无所事事强。
参考:
https://www.jianshu.com/p/7325b2ef8fc9
https://blog.csdn.net/u012991692/article/details/80866826
https://www.cnblogs.com/zhaijiahui/p/9147595.html
https://blog.csdn.net/nzjdsds/article/details/98763063