web文件上传漏洞及webload-labs靶场21关讲解
一、文件上传方式
1、发送文件
2、服务器接收
服务器接收到文件后,会将他储存到临时目录中。注:此过程要确保服务器能够正确处理文件并防止恶意文件直接执行
3、网络程序判断
(1)文件类型验证:确认文件的扩展名和MIME类型,确保它符合预期类型。
(2)内容扫描:检查文件内容,确保其中没有恶意代码或脚本。
(3)文件大小限制:对文件大小进行限制,以防止过大的文件占用过多的储存空间或消耗过多的服务器资源。
4、临时文件移动到指定路径
文件经过验证后,通常会被移动到最终的存储位置。这个位置是安全的,避免直接暴露给用户。
(1)路径安全:确保文件储存路径没有任何可以利用的漏洞。
(2)执行权限:对于储存目录,最好禁用执行权限,以防止上传的脚本被执行,防止未经授权的访问。
(3)清理和监控:定期清理上传的文件,并监视文件上传活动,以检测异常或恶意行为。
5、文件上传错误代码
0:没有错误,文件成功上传。
1:上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
2: 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
3:文件只有部分上传
4:文件没有被上传
二、文件上传漏洞
1、类型:

2、判断方法

3、前端验证
-
文件大小:确保上传的文件不超过服务器设置的最大文件大小限制。
-
文件类型:检查文件扩展名或MIME类型,确保只有允许的文件类型可以上传。
-
文件名:防止非法字符或敏感数据被包含在文件名中。
-
图像尺寸:特别是对图像文件,可以检查其尺寸符合特定要求。
4、后端验证
-
文件大小:和前端类似,但是在服务器端再次验证是必不可少的安全措施。
-
文件类型:通过检查文件的实际内容(比如文件的魔数/签名)来确定其类型,而不只是依赖于扩展名,因为扩展名可以被伪造。
-
文件内容:扫描文件内容,确保没有恶意代码或不合规的数据。
-
用户权限:验证上传文件的用户是否有足够的权限进行该操作。
三、一句话木马(webshell)
1、介绍
一句话木马是一种常见的网络安全攻击工具,通常用于web服务器的非法控制。被称为一句话是因为攻击者只需在目标服务器上的一个可访问的web页面中植入一小段代码,就可以实现对服务器的远程控制。
这种木马通常使用PHP、ASP、JSP等服务端脚本语言的形式出现。一句话木马的代码很简短但是功能非常强大,能够接受远程命令并在服务器上执行这些命令。
例如,一个PHP语言的木马可能看起来像这样:
<?php @eval($_POST['password']);?>
在这段代码中,‘password’不是传统意义上的密码,而是一个参数名称,用于传递执行代码到服务器是的一句话木马。通常隐藏在一个合法的服务器文件中。攻击者通过发送HTTP POST请求,并在i请求体中包含‘password’参数来传递他们想要执行的代码。
举例来讲,攻击者可能会发送一个包含如下数据的POST请求:
password=phpinfo();
在服务端,
$_POST['password']会接受到phpinfo();这段PHP代码。然后,当服务器上的一句话木马执行eval($_POST['password'])时,它会执行phpinfo();函数,这会导致服务器显示出PHP的配置信息。注:这个参数名称 'password' 在这里只是用作远程传递代码的一个占位符,并不是用作身份验证。攻击者通常会选择一个不太引人注意的参数名,以避免激起安全软件或管理员的怀疑。在实际攻击中,攻击者可能会选择任何名称作为参数,不一定是 'password'。
2、作用(危害)
一旦一句话木马被上传并植入到web服务器,攻击者就可以通过web请求与之交互,进行多种恶意操作,比如:
-
数据窃取:访问数据库,盗取敏感信息。
-
网站篡改:修改网站内容或数据库。
-
服务器控制:作为跳板进一步渗透内网,安装更多的恶意软件。
-
建立后门:长期控制和访问服务器。
-
分布式拒绝服务(DDoS)攻击:利用服务器作为攻击其他目标的资源。
由于一句话木马非常隐蔽,且通常体积很小,因此很难被发现。它们可能会通过各种方式被上传到服务器,例如利用文件上传漏洞、开发者的错误配置、甚至是通过第三方组件的安全漏洞。
3、一句话木马的防御
-
使用文件上传白名单,只允许特定类型的文件上传。
-
设置适合的文件权限,避免服务器上的文件被恶意修改。
-
定期更新和打补丁,修复已知的安全漏洞。
-
使用web应用防火墙(WAF)或其他入侵检测系统来识别和阻止木马活动。
-
定期进行安全审计和代码审查。
-
对上传的文件进行扫描,检查可能的恶意代码。
总的来说,一句话木马是一个非常危险的安全威胁,需要网站管理员和安全专业人员保持警惕,并采取适当的安全措施来防范
四、upload-labs 21关详解
靶场搭建:
链接: https://pan.baidu.com/s/1oZ3j6My50xJw2XpauxkUSA
提取码: 5401
-
-
蚁剑安装:
可以看这篇文章:中国蚁剑安装-保姆级教程_蚁剑安装教程-CSDN博客
-
-
-
简而言之,我们需要做的,就是借助各种工具,想尽一切方法,绕过靶机的前段和后端验证,上传一句话木马到服务器中并使服务器成功执行,然后使用命令执行的方法获得控制权限,找到有用的信息,在CTF比赛中,这个信息通常被称为flag。
-
请注意,由于upload-labs是每一关共享一个上传文件夹,所以我们每做出来一体,都需要清空上传文件,不然做下一题的时候之前的一句话木马依然在生效,避免混淆!
Pass01(客户端验证-前端)
-
先写一个webshell;
尝试上传一次发现网页直接阻止上传

此时文件并没有响应,故而为客户端验证,即前端验证;
也可以点击显示源码;
通过分析源代码,这个页面是通过分析文件的后缀而阻止文件上传的。
方法一(关闭网页的前端检测)
1、F12打开页面检查
右上方或左下方点击三个点,设置;

2、在设置里面找到调试程序,打开“禁用javascript"

3、上传webshell
上传成功

方法二(利用抓包软件)
1、先将文件扩展名该为图片(jpg.phg.gif)
确保不会被直接阻止上传
2、打开bp软件
开启拦截,上传数据包,让bp拦截,修改文件扩展名为php然后放行;


3、成功上传

Pass02(文件类型校验-MIML校验)
先尝试上传一个webshell;

网页在响应以后表示文件类型错误,说明这是一个后端验证。
解题方法
1、用bp抓包
找到数据包的文件类型

2、修改文件类型

3、放行后文件长传成功

MIME类型
MIME类型是一种标准,用来表示文档,文件或字节流的本质和格式。
MIML类型在HTTP协议中通过Content-Type头部字段来指定,格式通常为类型/子类型,例如:
-
text/html:表示HTML格式的文本文档
-
image/jpeg:表示JPEG格式的图片
-
application/json:表示JSON格式数据
-
audio/mpeg:表示MP3或其他MPEG音频
-
video/mp4:表示MP4视频文件
服务器在发送响应时会包含Content-Type头部,一告诉客户端如何处理接受到的数据。浏览器或其他客户端接收到数据后,会查看Content-Type头部,然后决定使用正确的处理器或应用程序来打开内容。
源代码解析

-
定义两个变量
$is_upload和$msg,分别用来标记是否上传成功和存储可能出现的消息提示。
-
通过
if (isset($_POST['submit']))检查是否有表单提交动作。$_POST['submit']通常来自一个按钮元素,当用户点击这个按钮时,表单会提交。
-
if (file_exists(UPLOAD_PATH))检查定义的UPLOAD_PATH目录是否存在。这里UPLOAD_PATH应该是一个常量,需要在脚本中事先定义,代表文件应该上传到的目标目录。
-
接下来的
if语句检查上传的文件类型是否为JPEG, PNG或GIF图片。$_FILES['upload_file']['type']包含了文件的MIME类型,这是通过文件上传处理时浏览器提供的。
-
$temp_file = $_FILES['upload_file']['tmp_name']从全局$_FILES数组中获取临时文件的路径。$_FILES数组是用来访问通过HTTP POST方法上传的文件的。
-
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']设置上传文件的最终保存路径,$_FILES['upload_file']['name']是上传文件的原始名称。
-
move_uploaded_file($temp_file, $img_path)尝试把临时文件移动到目标路径。如果成功,$is_upload将被设置为true。
-
如果
move_uploaded_file()失败,则设置$msg为'上传出错!'。
-
如果上传的文件类型不是JPEG, PNG, 或GIF,则
$msg会被设置成'文件类型不正确,请重新上传!'。
-
如果
UPLOAD_PATH目录不存在,则$msg会提示需要手动创建。
Pass03(文件类型校验-黑名单绕过)
先尝试上传一下webshell

如图,发现不允许上传一些后缀的文件
方法二
文件无法上传.php的文件,而php文件不一定要用php做后缀。
PHP脚本还有其他扩展名:
-
.php-最常见的PHP扩展名。
-
.php3-早期的PHP版本使用的扩展名。
-
.php4-使用PHP4.x系列
-
.php5 - 用于PHP 5.x系列。
-
.php7 - 用于PHP 7.x系列。
-
.php8 - 用于PHP 8.x系列。
-
.phtml - 这是PHP混合HTML文件使用的另一个旧扩展名。
-
.phps - 用来显示源代码的高亮显示而不是执行它。
-
.html or .htm - 有时服务器被配置为执行嵌入在HTML文件中的PHP代码。
-
.inc - 有时用于包含文件,但这不是一个安全做法,因为它可能会暴露敏感代码。
因为这些扩展名也可以运行php代码,而黑名单中没有禁止这样的扩展名(比赛中一般不会告诉黑名单中的扩展名),故而用这样的扩展名直接上传就可以成功;

方法二
根据第一题,发现可以用bp抓包修改文件后缀
1、打开bp抓包

2、修改文件后缀

3、放行数据包
上传成功

源代码解析

-
初始化变量
$is_upload为false和$msg为null。这两个变量分别用于跟踪上传状态和存储消息。
-
检查是否有POST请求,并且这个POST请求中是否包含了名为
submit的字段。如果存在,代表用户提交了表单。
-
使用
file_exists函数检查UPLOAD_PATH常量所指定的目录是否存在。这个常量应该在其他地方定义,用来指定上传文件保存的目录。
-
定义一个数组
$deny_ext,其中包含不允许上传的文件扩展名。在这个例子中,.asp、.aspx、.php和.jsp文件是不允许上传的,因为它们可能被用来上传恶意脚本到服务器。
-
获取上传文件的名字,并使用
trim函数移除文件名末尾的点。deldot函数的实现在代码段之外,它可能用于移除文件名末尾的不必要的点字符。
-
使用
strrchr函数获取文件名中最后一个点.后面的字符串,即文件的扩展名。
-
转换扩展名为小写,并去除可能存在的
::$DATA字符串。这个字符串可能与NTFS文件系统的流有关,其存在可能是为了防止一种特定的上传攻击。
-
使用
trim函数去除扩展名两边的空格。
-
使用
in_array函数检查文件扩展名是否在禁止上传的列表中。如果不在,继续处理上传。
-
获取上传文件的临时路径。
-
设置最终保存上传文件的路径,文件名由当前日期时间和一个随机数组成,以避免文件名冲突。
-
使用
move_uploaded_file函数将文件从临时目录移动到指定的上传目录。如果移动成功,则将$is_upload设置为true;如果移动失败,则设置$msg为错误消息。
-
如果文件扩展名在禁止上传的列表中,则设置
$msg为相应的错误消息。
-
如果
UPLOAD_PATH所指定的目录不存在,则设置$msg为错误消息。
Pass04(文件后缀校验-.htacess绕过)
先尝试上传一下webshell

方法一
同Pass03的方法一
方法二
1、此文件不允许上传,尝试一下图片能不能上传;

2、图片上传成功,因此我们可以把webshell改为一个图片马去上传;
只需新建一个文本文档,将代码写入后将文件扩展名改为.png/.jpg,就可以做成一个图片马,即可上传成功。


复制图片链接,发现无法运行
3、此时复制链接打开网页无法执行,这时候需要创建.htaccess文件
SetHandler application/x-httpd-php

再上传到靶场;

再复制链接打开,代码执行成功;

源代码解析

-
文件类型限制
通过$deny_ext数组定义一系列不允许上传的文件扩展名。这些扩展名主要包括了多种不同版本的PHP文件(如.php, .php5, .php4等),HTML文件(如.html, .htm等),以及其他可以执行的Web脚本文件扩展名(如.jsp, .asp, .aspx, .swf等)。 它的目的是阻止用户上传可能包含恶意代码的文件,这些文件若被服务器执行,可能会给服务器安全带来严重威胁。
-
文件名处理
使用trim函数删除文件名末尾的点(.)。这是为了避免绕过文件类型的检查。 采用strrchr函数抽取文件名中最后一个.之后的所有字符作为文件扩展名,并通过strtolower转换成小写,确保大小写不会影响扩展名的判断。 使用str_ireplace去除文件扩展名中可能的::$DATA字符串。这是一种特定的NTFS文件流技术,通过它可能会绕过一些简单的文件类型检测。
-
文件上传条件
检查UPLOAD_PATH定义的目录是否存在,如果不存在,则给出提示信息。这是一个基本的检查,确保文件有一个正确的存储位置。 如果目标文件的扩展名不在禁止列表$deny_ext中,那么尝试将文件从临时位置移动到指定的上传路径。使用date("YmdHis").rand(1000,9999)生成的字符串为文件名,加上原始文件扩展名,这减少了文件重名的可能性,并为每个上传的文件提供了一定程度上的匿名性。 如果文件移动成功,$is_upload将被设为true,表示上传成功;否则,将给出上传出错的提示信息。
Pass05(文件后缀绕过-双写绕过)
先上传一个webshell;

解题方法
1、查看源代码

可以看到对很多后缀进行了过滤,包括上一关用到的.htascess文件,还对很对特殊的绕过方式进行了限制,但是仔细观察会发现这里它对文件末尾的点仅仅限制了一次,那么我们就可以尝试使用两个点来绕过限制,上传php文件.
2、上传php文件使用BP抓包,修改后缀;
在php后面加上“。。”

3、放行查看结果

上传成功
Pass06(文件后缀校验-大小写绕过)
尝试上传一个webshell;

解题方法
1、打开源代码

对比第五关的源码可以发现,第六关的源码没有把字符强制转换为小写的语句:
$file_ext = strtolower($file_ext); //转换为小写
在这行代码中,strtolower函数被用于将变量$file_ext所包含的字符串转化为全小写。
2、这里我们就直接通过Burpsuite抓包修改文件名了。
将 yjh.php 修改为 yjh.Php 。由于第五关的脚本并没有做大小写限制,所以这里可以非常容易的绕过限制,达到上传成功的目的。

3、放行查看结果

上传成功
-
总结一下: 这题就是服务器没有对上传文件的名称大小写进行限制,从而导致大小写绕过漏洞,攻击者可以通过替换文件名为大写绕过对.php的限制上传恶意代码。
Pass07(文件后缀绕过-空格绕过)
上传webshell尝试

解题方法
1、打开源代码查看

第七关中对文件后缀进行首尾去空的代码为:
$file_ext = trim($file_ext); //首尾去空
这一行代码使用了PHP的
trim函数对变量$file_ext所存储的字符串进行处理。trim函数的作用是去除字符串首尾的空白字符(包括空格、换行符、制表符等)所以这里可以通过对文件后缀名末尾进行添加空格的方式来进行绕过。
2、用BP抓包处理,在首尾加空格

3、放行查看结果

上传成功
Pass08(文件名后缀校验-点号绕过)
尝试上传一个webshell

解题方法
1、查看源代码

显而易见,deldot()函数没有了,那么我们就可以抓包在文件名的末尾加一个.来绕过限制,从而上传php文件。
2、打开BP抓包,修改后缀

3、放行查看结果;

上传成功
Pass09(文件名后缀校验-::$DATA绕过)
先尝试上传一个webshell文件;

解题方法
1、查看源代码

显而易见,str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA的这个函数没有了
2、打开BP抓包,修改后缀;

3、放行查看结果

上传成功
Pass10(文件名后缀校验-拼接绕过)
先尝试上传一个webshell;

分析源代码;

观察源代码发现,这关文件限制很全面。但是它仍然只删除一个点;
解题方法
与第五关相同,使用BP双写绕过


上传成功
Pass11(文件后缀名校验-双写绕过)
先尝试上传一个webshell;

与之前几道题不同,这次显示的是“上传出错”;
解题方法
1、查看源代码

显而易见,如果上传的文件如果是黑名单的任意一个,就会将文件的后缀替换为空,故而可以使用双写绕过黑名单;
2、打开BP,修改后缀;

3、放行查看结果;

上传成功
Pass12(白名单校验-GET型0x00截断)
尝试上传一个webshell文件;

根据提示,只允许我们上传.jpg|.png|.gif类型的文件
解题方法
1、查看源代码

由此可知,使用了白名单机制只允许上传指定后缀的文件,这里可以修改文件扩展名来进行上传。
2、用BP抓包,然后将文件扩展名修改为“.jpg"

3、放行查看结果;

上传成功
Pass13(白名单校验-POST型0x00截断)
尝试上传一个webshell文件

与上一关相同只允许上传.jpg|.png|.gif|类型的文件,所以我们依然可以通过修改文件扩展名后缀的方式上传。
解题方法
1、打开BP抓包,修改扩展名。

2、放行查看结果;

上传成功
Pass14(文件内容检测-文件头校验)
第14关让我们上传图片马,并且又一下要求:
-
保证上传后的图片马中仍然包含完整的
一句话或webshell代码。
-
使用文件包含漏洞能运行图片马中的恶意代码。
-
图片马要
.jpg,.png,.gif三种后缀都上传成功才算过关!
解题方法
1、查看源代码;

发现它只读取开头两个字节;
2、创建图片马;
(1)写一句话木马
(2)随便找一张图片,二者放入同一文件夹下

(3)将木马与图片进行融合
在文件夹上方打开cmd

利用系统命令(copy san.png/b + muma.php/a)生成图片马;

(4)上传生成好的一句话木马:

上传成功
Pass15(文件内容检测-getimagesize()校验)
先尝试上传一个webshell;

解题方法
1、查看源代码;

源代码使用了getimagesize()函数
-
getimagesize函数:
getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型和一个可以用于普通 HTML 文件中 IMG 标记中的 height/width 文本字符串。
它会对目标文件的16禁止区进行读取文件头的几个字符串是不是符合图片的要求,那么我们还可以使用上面的一句话木马图片
2、我们还可以使用上面的一句话木马图片;


上传成功
##Pass16(文件内容检测-exif_imagetype()绕过)
先尝试上传一个webshell文件;

页面黑屏了
解题方法
1、查看源代码

使用了exif_imagetype()函数;
-
exif_imagetype()函数:用于判断一个图像的类型,它读取一个图像的第一个字节并且检查其后缀名。需要在phpstudy中开启php.exif选项才可以使用
2、我们还可以使用上面的一句话木马图片;

Pass17
先尝试上传一个webshell;

发现只能上传后缀为.jpg|.png|.gif|类型的图片;
解题方法
我们依然可以使用之前的一句话木马图片;


上传成功;
Pass18
先尝试上传一个webshell文件;

解题方法
1、查看源代码

2、打开BP抓包,修改文件扩展名;

3、放行查看结果

上传成功
Pass19
先尝试上传一个webshell文件

无法上传该类型文件;
解题方法
1、打开BP抓包,修改文件扩展名;

2、放行查看结果;

上传成功
Pass20(逻辑漏洞-./绕过)
先尝试上传一个webshell文件

解题方法
1、查看源代码;

可以看到还是move_uploaded_file函数对上传的文件就进行了处理,这里需要利用这个函数的一个特性,会忽略’/.‘
2、我们可以尝试使用BP抓包,然后对文件名修改再上传:

3、放行查看结果

上传成功
Pass21(逻辑漏洞-小数点绕过)
先尝试上传一个webshell文件;

解题方法
1、查看源代码

查看代码发现有以下步骤:
-
检查MIME (通过抓包改Content-Type 绕过)
-
判断 POST参数 save_name 是否为空
-
判断$file 是否为数组,不是数组以 .分割化为数组
-
取 $file 最后一个元素,作为文件后缀进行检查
-
取 f i l e 第 一 位 和 第 ‘ file 第一位和第
file第一位和第‘file[count($file) - 1]作为文件名和后缀名保存文件。
2、打开BP抓包,修改文件类型

3、放行查看结果;

上传成功
-
-
更多推荐


所有评论(0)