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

upload-labs详解(1-12)文件上传分析

目录

uploa-labs-main

upload-labs-main第一关

前端防御

绕过前端防御

禁用js

Burpsuite抓包改包

upload-labs-main第二关

上传测试

错误类型

upload-labs-env

upload-labs-env第三关

上传测试

查看源码

解决方法

重命名,上传

upload-labs-env第四关

测试方法

上传文件

upload-labs-env第五关

代码解析

解题思路——大小写绕过

upload-labs-env第六关

代码

空格绕过

upload-labs-env第七关

代码

绕过

upload-labs-env第八关

::$DATA 绕过

upload-labs-env第九关

代码

思路

upload-labs-env第十关

代码

双写绕过

upload-labs第-env十一关

代码

思路——00截断问题(只存在于php5.2版本中)——get传参(url编码方式)

upload-labs-env第十二关

代码

思路——00截断——save_path是post传参


uploa-labs-main

upload-labs-main第一关

前端防御

有一个过滤函数checkFile()

绕过前端防御

禁用js

Chrome禁用js

设置—隐私与安全—网站设置—内容—JavaScript—不允许网站使用JavaScript

再次尝试上传,成功

Burpsuite抓包改包

首先为文件进行重命名,shell.php重命名为shell.jpg

上传shell.jpg文件

Burpsuite打开抓包

网页点击确定上传,

发送到重放器,改包,将shell.jpg改为shell.php,重新发送,上传成功

upload-labs-main第二关

上传测试

错误类型

文件类型不正确,

使用Burpsuite抓包改包

修改为image/png

上传成功

upload-labs-env

upload-labs-env第三关

上传测试

查看源码

 $is_upload = false;$msg = null;if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array('.asp','.aspx','.php','.jsp');//定义一个数组$deny_ext,包含不允许上传的文件扩展名$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空​if(!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];//获取上传文件的临时路径,文件在服务器上以临时文件的形式存储$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}}

分析源码

需要绕过黑名单的过滤

.php3 、Phtml等都可以被解析

需要修改Apache的配置文件httpd.conf,使.php3 .phtml也可以被解析,当Apache和php版本低时,服务端可以修改

在配置文件中添加

 AddType application/x-httpd-php .phtml

重启Apache

注意:在靶场实验中可能存在这个漏洞,真实项目中不会存在

解决方法

黑名单绕过

在upload-labs-env原版环境中,Apache的配置文件httpd.conf有将 .php3 .phtml解析成php文件

重命名,上传

上传成功

解析成功

upload-labs-env第四关

测试方法

需要.htaccess文件

我们下载upload-labs-env原版环境,自带phpstudy的低版本

在Apache的低版本中,如果在目录中上传一个.htaccess文件

AddType application/x-httpd-php .jpg

会将后来上传的jpg文件解析成php,shell代码得以执行

上传文件

解析成功

upload-labs-env第五关

代码解析

$is_upload = false;
$msg = null;# isset - 检测变量是否已经声明并且不为空
# $_POST['submit'] - 表示表单中名为 submit 的按钮被点击
if (isset($_POST['submit'])) {# file_exists — 检查文件或目录是否存在返回值为true或falseif (file_exists(UPLOAD_PATH)) {# 定义一个数组 $deny_ext,包含一系列禁止上传的文件扩展名$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");# trim — 去除字符串首尾处的空白字符(或者其他字符)# $_FILES['upload_file'] 是表单中 name="upload_file" 对应的上传文件信息# 它包含以下常见字段:# $_FILES['upload_file']['name']:上传文件的原始名称(如 example.jpg)。# $_FILES['upload_file']['type']:上传文件的 MIME 类型(如 image/jpeg)。# $_FILES['upload_file']['size']:上传文件的大小(以字节为单位)。# $_FILES['upload_file']['tmp_name']:上传文件的临时存储路径。# $_FILES['upload_file']['error']:与文件上传相关的任何错误代码$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点#strrchr — 查找指定字符在字符串中的最后一次出现的位置,返回从最后一个点开始到字符串末尾的部分$file_ext = strrchr($file_name, '.');#str_ireplace - 执行不区分大小写的字符串替换,在目标字符串中查找指定的子字符串(无视大小写),然后用另一个字符串替换它$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空#in_array — 检查数组中是否存在某个值,检查数组$deny_ext中是否存在$file_extif (!in_array($file_ext, $deny_ext)) {# $_FILES['upload_file']['tmp_name']:上传文件的临时存储路径。$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;#move_uploaded_file — 将上传的文件移动到新位置if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

解题思路——大小写绕过

文件后缀大写绕过

上传.php文件

修改后缀名为.PHP

上传成功

解析执行

upload-labs-env第六关

代码

        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");$file_name = $_FILES['upload_file']['name'];$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

空格绕过

文件名后缀加空格绕过

upload-labs-env第七关

代码

        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");$file_name = trim($_FILES['upload_file']['name']);$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空

绕过

文件后缀名后加点

upload-labs-env第八关

::$DATA 绕过

upload-labs-env第九关

代码

没有对代码进行重命名拼接路径

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空if (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

思路

deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来

更改文件名为 index.php. . 即.php点 空格 点

运行php时,首先删除文件名末尾的点,

...... ,

最后一步检查,去除最后的空格,

此时文件名为index.php.

上传到Windows环境中时,系统会将其视为一个没有扩展名的文件,

Windows会将 index.php. 解释为没有扩展名的文件,因为末尾的点会被忽略。文件的实际名称会变成 index.php,但扩展名会被视为不存在

upload-labs-env第十关

代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_name = str_ireplace($deny_ext,"", $file_name);$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;        if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

使用str_ireplace()函数寻找文件名中存在的黑名单字符串,将它替换成空(即将它删掉),可以使用双写绕过黑名单

双写绕过

upload-labs第-env十一关

代码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');//$_FILES['upload_file']['name']:获取上传文件的原始文件名//strrpos($_FILES['upload_file']['name'], "."):查找文件名中最后一个点(.)的位置//substr(..., strrpos(...) + 1):从最后一个点的下一个字符开始截取,得到文件扩展名$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){//$_FILES['upload_file']['tmp_name']:获取上传文件的临时存储路径$temp_file = $_FILES['upload_file']['tmp_name'];//$_GET['save_path']:从 URL 参数中获取保存路径//rand(10, 99):生成一个 10 到 99 之间的随机数//date("YmdHis"):生成当前日期时间字符串,格式为 年月日时分秒//最终路径格式:保存路径/随机数+时间戳.扩展名$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = '上传出错!';}} else{$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}

思路——00截断问题(只存在于php5.2版本中)——get传参(url编码方式)

在c语言中\0是结束符

php底层是运行c语言

使用\0使截断代码,使后面代码不再运行

使用的传递方式是urlcode传参,%00使用url解码后为空字符

当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃

当php代码运行到

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){

时,路径变成了/upload/web.php 后面的连接字符都被丢弃了,

之后将文件上传文件index.jpg的文件内容移动到web.php中,这样恶意代码就可以被解析了

upload-labs-env第十二关

代码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传失败";}} else {$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}

思路——00截断——save_path是post传参

0x00 是十六进制表示的空字符(ASCII 值为 0)

在web.php后面加一个空格,在Burpsuite的hex转换中,找到这个空格(十六进制空格的编码为20)

将其修改为十六进制的空字符表示00

修改后

发送


http://www.mrgr.cn/news/93478.html

相关文章:

  • 【人工智能】Open WebUI+ollama+deepSeek-r1 本地部署大模型与知识库
  • Linux和gcc/g++常用命令总结
  • 【全球化2.0 | ZStack发布Zaku容器云海外版 加速亚太生态布局
  • Java面试第八山!《Spring框架》
  • BUUCTF逆向刷题笔记(1-12)
  • 【零基础C语言】第五节 函数
  • Android实现漂亮的波纹动画
  • 【OMCI实践】wireshark解析脚本omci.lua文件(独家分享)
  • 前端实现版本更新自动检测✅
  • DeepSeek V3 源码:从入门到放弃!
  • 现代密码学体系架构设计原则与实践:基于Python的实现与GPU加速GUI演示
  • 【docker】安装mysql,修改端口号并重启,root改密
  • Anolis服务器Arm64架构服务器配置(其他版本服务器解决方式思路一质)
  • JDK ZOOKEEPER KAFKA安装
  • Vue 系列之:组件通讯
  • 在线教育网站项目第二步 :学习roncoo-education,服务器为ubuntu22.04.05
  • react中的fiber和初次渲染
  • 树莓派3B+的初步使用
  • 【VBA】WPS/PPT设置标题字体
  • Java本地缓存深度实践:框架选型与一致性保障(下)