当前位置: 首页 > news >正文

upload-labs 21关解析

目录

一、代码审计

二、实践

三、总结


一、代码审计

$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){//检查MIME$allow_type = array('image/jpeg','image/png','image/gif');if(!in_array($_FILES['upload_file']['type'],$allow_type)){$msg = "禁止上传该类型文件!";}else{//检查文件名$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];if (!is_array($file)) {$file = explode('.', strtolower($file));}$ext = end($file);$allow_suffix = array('jpg','png','gif');if (!in_array($ext, $allow_suffix)) {$msg = "禁止上传该后缀文件!";}else{$file_name = reset($file) . '.' . $file[count($file) - 1];$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' .$file_name;if (move_uploaded_file($temp_file, $img_path)) {$msg = "文件上传成功!";$is_upload = true;} else {$msg = "文件上传失败!";}}}
}else{$msg = "请选择要上传的文件!";
}

对源代码进行分析

$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];

这是个三元运算符,判断 'save_name' 是否为空 

(A ? B : C  ,如果A成立,则运行B,否则运行C)

如果用户提交的'save_name'为空,则使用上传文件的原始文件名,若不为空则使用该参数值作为文件名

 if (!is_array($file)) {$file = explode('.', strtolower($file));}

判断 $file 是不是数组,如果不是数组,则使用 . 进行切分变为数组

比如 cooper.php.jpg,切分为 cooper php jpg 分别对应数组三个元素

 $ext = end($file);

从数组中获取最后一个元素作为扩展名

经过这两条分析,想想为什么要判断 'save_name' 参数是否为数组呢?

难道POST提交的不都是字符串吗?

那么就进行测试

发现请求参数可以直接以数组的方式提交

那么我们能否去构造一个POST请求的save_name参数,将文件后缀名改为jpg,但文件本身还是cooper.php

问题保留一下,接着分析

$file_name = reset($file) . '.' . $file[count($file) - 1];

reset函数为调用第一个元素

拼接文件名:数组第一个元素 + . + 数组最后一个元素

比如文件名为cooper.php,则 $file_name = cooper + . + php

那么如果直接上传的不是字符串,而是数组会怎么样?

比如save_name[0] = cooper.php , save_name[2] = jpg

按照拼接方法那我们构造的文件最后的方式为:

$file_name = cooper.php . $file[1]   ==> cooper.php.空

理论可行,实践开始!

二、实践

首先上传一个带有木马的php文件,使用burp抓包

.

将其修改为以下格式

提示上传成功,那么就来测试一下

试验成功!

三、总结

复盘一下:先进行代码审计,然后看到分割数组,思考为什么要进行分割,难道POST可以上传数组吗?然后进行实验,实验验证确实可以上传数组形式。接着代码审计,发现文件拼接时具有漏洞,那么构造payload进行尝试,最后成功!

相关文章:

  • 手把手教你写Java项目(1)——流程
  • 什么是深拷贝和浅拷贝?
  • 微服务架构的优势 与 不足
  • 常见排序算法之选择排序
  • 内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机
  • 微信生态系统介绍
  • Android 待办类应用提醒功能的实现及其问题
  • ⌈ 传知代码 ⌋ 高速公路车辆速度检测软件
  • 全同态加密生态项目盘点:FHE技术的崛起以及应用
  • 编译链接问题
  • 面试的内容
  • java面试(多线程)
  • Canny算子
  • 幼儿园老师投稿渠道
  • 01 一文理解,Prometheus详细介绍
  • 2019.2.20 c++ 知识梳理
  • const let
  • create-react-app项目添加less配置
  • js算法-归并排序(merge_sort)
  • MySQL QA
  • node-glob通配符
  • node和express搭建代理服务器(源码)
  • Python_网络编程
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • Vue2.x学习三:事件处理生命周期钩子
  • Webpack 4x 之路 ( 四 )
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 强力优化Rancher k8s中国区的使用体验
  • 思考 CSS 架构
  • 为什么要用IPython/Jupyter?
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 用element的upload组件实现多图片上传和压缩
  • 用jquery写贪吃蛇
  • 主流的CSS水平和垂直居中技术大全
  • 7行Python代码的人脸识别
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​如何使用QGIS制作三维建筑
  • ​学习笔记——动态路由——IS-IS中间系统到中间系统(报文/TLV)​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # 数论-逆元
  • (02)Unity使用在线AI大模型(调用Python)
  • (1)Hilt的基本概念和使用
  • (Note)C++中的继承方式
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (分布式缓存)Redis持久化
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (三)终结任务
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)3D模板阴影原理
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .Net - 类的介绍
  • .NET Core中Emit的使用
  • .NET Micro Framework初体验(二)
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter