皮卡丘Unsafe Fileupload

news2024/11/23 10:13:02

1.不安全的文件上传漏洞概述

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

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

2.client check

我们试试上传phpninfo文件,命名为1.php

提示说不符合文件要求

看提示说只让上传图片文件

我们把1.php后缀改为.png,开始上传并抓包,再send to repeater

再把文件名改回成1.php,点send,php文件上传成功,且暴露了路径

访问:http://127.0.0.1/pk/vul/unsafeupload/uploads/1.php

成功! 

3.MIME type

看提示说还是只允许上传图片

但我们不听他的,照样上传1.php,提示又说只能是jpg,jpeg,png形式的

那我们继续把1.php后缀改为.png,开始上传并抓包,再send to repeater

后面的过程就和第一题一样了,也能成功访问:http://127.0.0.1/pk/vul/unsafeupload/uploads/1.php

那么不同之处在哪呢

查看本关的防护源代码

$mime是一个包含合法MIME类型的数组,也就是MIME类型白名单;然后将这个白名单作为参数传入了upload_sick()函数进行服务器端的检测。

只有上传文件的MIME类型包含在预定义的MIME白名单之中时,才允许上传,即只允许上传'image/jpg'、'image/jpeg'、'image/png'这三种MIME类型的文件  

upload_sick()函数的定义如下,该函数不安全之处在于两点:

(1)仅检查了MIME类型,可以通过抓包修改绕过。

(2)保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。

整个关卡还有一处不安全,就是和第一关一样,同样回显了文件保存路径。

成功上传webshell,并且知道文件保存路径后,攻击者就可以连接shell了。

4.getimagesize

这关就有所不同了,尝试前两关的方法,我们上传1.png,结果如下

发现这次我们的伎俩被识破了。。。。。

试试上传一个真的jpeg文件,结果如下,可见后端代码修改了文件名,但是还把文件保存路径回显了出来

getimagesize看起来像是个函数,用搜索引擎搜索,结果如下:

getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。

getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。

查看源码:

getimagesize()文件中截取的关键代码片段,可以发现通过调用upload()函数来实现getimagesize()检测功能,其中upload()函数在外部文件uploadfunction.php文件中定义,并通过include_once来引入。

接下来,再分析具体实现文件类型检测功能的upload()函数,定位到uploadfunction.php文件,截取其中关于upload()函数的定义代码,upload()定义了5个参数,分别为$key,$size,$type,$mime,$save_path,其中$key取值为“uploadfile”,代表form表单中<input>的name属性、$size限制上传文件大小、$type代表允许上传的文件类型白名单,$mime代表允许MIME类型白名单、$save_path代表文件上传后的存储路径

可见,在Pikachu靶场getimagesize检测时,分别依次检测文件大小、检测文件类型、检测文件MIME类型3中方式来实现检测,加强文件上传过滤效果,且在进行文件保存的时候以随机数为文件名进行保存,因此在绕过的时候需要同时绕过这三个检测手段

//进行了严格的验证
function upload($key,$size,$type=array(),$mime=array(),$save_path){
    $arr_errors=array(
        1=>'上传的文件超过了 php.ini中 upload_max_filesize 选项限制的值',
        2=>'上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',
        3=>'文件只有部分被上传',
        4=>'没有文件被上传',
        6=>'找不到临时文件夹',
        7=>'文件写入失败'
    );
//     var_dump($_FILES);
    if(!isset($_FILES[$key]['error'])){
        $return_data['error']='请选择上传文件!';
        $return_data['return']=false;
        return $return_data;
    }
    if ($_FILES[$key]['error']!=0) {
        $return_data['error']=$arr_errors[$_FILES[$key]['error']];
        $return_data['return']=false;
        return $return_data;
    }
    //验证上传方式
    if(!is_uploaded_file($_FILES[$key]['tmp_name'])){
        $return_data['error']='您上传的文件不是通过 HTTP POST方式上传的!';
        $return_data['return']=false;
        return $return_data;
    }
    //获取后缀名,如果不存在后缀名,则将变量设置为空
    $arr_filename=pathinfo($_FILES[$key]['name']);
    if(!isset($arr_filename['extension'])){
        $arr_filename['extension']='';
    }
    //先验证后缀名
    if(!in_array(strtolower($arr_filename['extension']),$type)){//转换成小写,在比较
        $return_data['error']='上传文件的后缀名不能为空,且必须是'.implode(',',$type).'中的一个';
        $return_data['return']=false;
        return $return_data;
    }
    
    //验证MIME类型,MIME类型可以被绕过
    if(!in_array($_FILES[$key]['type'], $mime)){
        $return_data['error']='你上传的是个假图片,不要欺骗我xxx!';
        $return_data['return']=false;
        return $return_data;
    }
    //通过getimagesize来读取图片的属性,从而判断是不是真实的图片,还是可以被绕过的
    if(!getimagesize($_FILES[$key]['tmp_name'])){
        $return_data['error']='你上传的是个假图片,不要欺骗我!';
        $return_data['return']=false;
        return $return_data;
    }
    //验证大小
    if($_FILES[$key]['size']>$size){
        $return_data['error']='上传文件的大小不能超过'.$size.'byte(500kb)';
        $return_data['return']=false;
        return $return_data;
    }
 
    //把上传的文件给他搞一个新的路径存起来
    if(!file_exists($save_path)){
        if(!mkdir($save_path,0777,true)){
            $return_data['error']='上传文件保存目录创建失败,请检查权限!';
            $return_data['return']=false;
            return $return_data;
        }
    }
    //生成一个新的文件名,并将新的文件名和之前获取的扩展名合起来,形成文件名称
    $new_filename=str_replace('.','',uniqid(mt_rand(100000,999999),true));
    if($arr_filename['extension']!=''){
        $arr_filename['extension']=strtolower($arr_filename['extension']);//小写保存
        $new_filename.=".{$arr_filename['extension']}";
    }
    //将tmp目录里面的文件拷贝到指定目录下并使用新的名称
    $save_path=rtrim($save_path,'/').'/';
    if(!move_uploaded_file($_FILES[$key]['tmp_name'],$save_path.$new_filename)){
        $return_data['error']='临时文件移动失败,请检查权限!';
        $return_data['return']=false;
        return $return_data;
    }
    //如果以上都通过了,则返回这些值,存储的路径,新的文件名(不要暴露出去)
    $return_data['save_path']=$save_path.$new_filename;
    $return_data['filename']=$new_filename;
    $return_data['return']=true;
    return $return_data;
    }

此时后端检测手段丰富,具有很强的过滤效果,无法直接上传php脚本文件。

那么,怎么绕过getimagesize ( )检测呢?

那便是制作图片木马

首先,我们准备php脚本,我们还用phpinfo,因为比一句话木马安全嘛

再准备一张图片

win+r输入cmd,进入命令提示符,先进入桌面,再输入命令dir,展示桌面的文件。

输入命令copy /b 666.png + 1.php 123.png,在桌面生成123.png的图片马。 

发现桌面上已经有该图片木马了

再回到题目上传该图片,发现上传成功!

确认一下文件上传到的路径和文件名称与回显信息是否一致 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/606635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python升序数函数:从入门到实战

Python升序数函数&#xff1a;从入门到实战 Python是一门广泛应用于软件开发、数据分析、人工智能等领域的高级编程语言。其中&#xff0c;对数值类型的处理尤为突出&#xff0c;而Python中提供了许多方便实用的数学函数来支持数值类型的计算。本篇文章将主要介绍Python中如何…

皮卡丘存储型xss、DOM型xss、DOM型xss-x

1.存储型xss 看题目&#xff0c;我们先留言&#xff0c;看它的过滤机制 发现可以永久存储并输出我们的留言 之后插入payload: <script>alert(xss)</script> 成功弹窗&#xff01; 2.DOM型xss Dom型xss&#xff0c;简单的说&#xff0c;就是向文档对象传入xss参…

ODOO随笔(一)—— Odoo 16的docker部署以及vscode环境配置

之前一直使用Odoo源码配置开发环境&#xff0c;安装的步骤比较多&#xff0c;费时。趁着升级到16版本的机会&#xff0c;尝试使用docker快速配置Odoo的VSCode开发环境。 1 系统环境 &#xff08;1&#xff09;操作系统&#xff1a;ubuntu 20.04 Alternative downloads | Ubu…

高完整性系统(1)Introduction

文章目录 什么是 formal methods案例1&#xff1a;造影机器案例2&#xff1a; 特斯拉汽车的自动驾驶功能案例3&#xff1a;空客 320案例4&#xff1a;波音737 什么是 formal methods “Formal methods” 是计算机科学中的一个术语&#xff0c;它指的是一种使用数学模型和技术来…

chatgpt赋能python:Python匹配空格

Python匹配空格 在Python中&#xff0c;空格是一个常见的字符&#xff0c;在字符串和文本处理中非常常见。但是&#xff0c;在某些情况下&#xff0c;我们需要匹配字符串中的空格&#xff0c;这个时候就需要使用Python匹配空格。 什么是Python匹配空格&#xff1f; Python匹…

皮卡丘反射型XSS

1.反射型xss(get) 进入反射型xss(get)的关卡&#xff0c;我们可以看到如下页面 先输入合法数据查看情况&#xff0c;例如输入“kobe” 再随便输入一个&#xff0c;比如我舍友的外号“xunlei”&#xff0c;“666”&#xff0c;嘿嘿嘿 F12查看源代码&#xff0c;发现你输入的数…

【5.29 代随_41day】 整数拆分、不同的二叉搜索树

整数拆分、不同的二叉搜索树 整数拆分1.动态规划的方法图解步骤代码 不同的二叉搜索树图解步骤代码 整数拆分 力扣连接&#xff1a;343. 整数拆分&#xff08;中等&#xff09; 1.动态规划的方法 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i]&#xff1a…

redis第四章-redis下redisson分布式锁原理和源码分析

如上图&#xff0c;在最简单使用分布式锁的时候&#xff0c;我们一般获取一个锁对象&#xff0c;对这个对象进行加锁&#xff0c;当执行完业务流程代码后&#xff0c;对分布式锁进行解锁&#xff0c;这样就保证了高并发下程序的锁安全&#xff0c;以及原子性。 如图&#xff0c…

Linux 实验三 Linux C开发工具的使用

做实验之前必须会vim的简单使用 会使用vi 进入文件 i 插入 esc进入底行模式 :wq退出 1、vi编辑器和gcc编译器的简单使用 &#xff08;1&#xff09;在用户主目录下新建一个目必须掌握录&#xff0c;命名为vifile &#xff08;2&#xff09;进入目录vifile &#xff08;3&…

LearnOpenGL-高级OpenGL-10.实例化

本人初学者&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 文章目录 实例化例子1.1&#xff1a;100个2D四边形使用Uniform 实例化数组例子1.2&#xff1a;100个2D四边形使用实例化数组例子2.1&#xff1a;行星带不使用实例化数组例子2.2&#xff1a;行星带使用实例…

【转码】nohup后台执行ffmpeg转码后推流srs

【ffmpeg】flv1转码h264且降低分辨率 【ffmpeg】filter_complex 转码视频保留音频推直播flv流 拉流播放剪辑到2M mp4 转flv 同时转码,拉流地址:http://1.1.1.5:8078/live/streamLow.flv 过了三个月,忘了。通过查询后台程序,判断当时自己是用的哪个脚本:看下上次操作的时间…

MySQL简单教程

MySQL的数据类型 类型用途int整型&#xff0c;相当于java的intbigint整型&#xff0c;相当于java的longfloat浮点型double浮点型datetime日期类型timestamp日期类型(可存储时间戳)char定长字符varchar不定长字符text大文本&#xff0c;用于存储很长的…

皮卡丘xss之盲打、xss之过滤

1.xss之盲打 我们先按照题目输入 提交后&#xff0c;很平常 再试试插入payload&#xff1a;<script>alert(1)</script>和<script>alert(2)</script> 提交后还是不变 此时我们看提示 我们尝试访问该地址&#xff1a;127.0.0.1/pk/vul/xss/xssblind/ad…

聊聊Scrum价值观与测试启发

这是鼎叔的第六十二篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。 敏捷理论博大精深&#xff0c;相关实践方法论和工具层出不穷&#xff0c;各大公司都有特…

从零开始学习JVM(六)-直接内存和执行引擎

1 直接内存介绍 直接内存不是虚拟机运行时数据区的一部分&#xff0c;也不是《Java虚拟机规范》中定义的内存区域。直接内存是在Java堆外的、直接向系统申请的内存空间。直接内存来源于NIO&#xff0c;通过存在堆中的DirectByteBuffer操作Native内存。通常访问直接内存的速度会…

Stable Diffusion教程

什么是Stable Diffusion Stable Diffusion是一种潜在扩散模型&#xff08;Latent Diffusion Model&#xff09;&#xff0c;能够从文本描述中生成详细的图像。它还可以用于图像修复、图像绘制、文本到图像和图像到图像等任务。简单地说&#xff0c;我们只要给出想要的图片的文…

RK3588平台开发系列讲解(网络篇)本地套接字

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、本地套接字是什么二、本地字节流套接字 服务器三、本地字节流套接字 客户端沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本地套接字是 IPC,也就是本地进程间通信的一种实现方式。除了本地套接字以外,…

皮卡丘Unsafe Filedownload

1.不安全的文件下载概述 文件下载功能在很多web系统上都会出现&#xff0c;一般我们当点击下载链接&#xff0c;便会向后台发送一个下载请求&#xff0c;一般这个请求会包含一个需要下载的文件名称&#xff0c;后台在收到请求后 会开始执行下载代码&#xff0c;将该文件名对应…

旧改快讯--桑泰南山桃源“工改商住”项目规划修改

南山区桃源街道西丽同富裕工业城城市更新单元原列入《2019年深圳市南山区城市更新单元计划第一批计划》&#xff0c;后进行更新方向调整&#xff0c;列入《2020年深圳市南山区城市更新单元计划第三批计划》&#xff0c;2022年8月发布实施主体公示&#xff0c;实施主体为深圳市桑…

chatgpt赋能python:Python到底是一个SEO友好的选择吗?

Python到底是一个SEO友好的选择吗&#xff1f; 随着Python成为越来越受欢迎的编程语言&#xff0c;人们开始担心它是否适用于SEO。因为SEO是一项关键性能指标&#xff0c;因此希望了解Python是否确实是适用于这一目标。 Python的SEO优缺点 首先&#xff0c;Python确实具有一…