当前位置: 首页 > 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或false
    if (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_ext
        if (!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

修改后

发送

相关文章:

  • 算法系列之数据结构-Huffman树
  • 【够用就好006】如何从零开发游戏上架steam面向AI编程的godot独立游戏制作实录001流程
  • AI绘画软件Stable Diffusion详解教程(7):图生图基础篇(改变图像风格)
  • 蓝桥杯题型
  • CAP三进二、Base原理和Raft算法
  • PDF 文件中的文本链接是如何定义的?
  • 简记_硬件系统设计之需求分析要点
  • 2025牛客寒假算法基础集训营6
  • Python自动化测试教程
  • Spring Boot 内置工具类,功能齐全!!
  • TTP/HTTPS、TCP/IP 协议、RPC、Socket 通信机制
  • 盛铂科技PDROUxxxx系列锁相介质振荡器(点频源):高精度信号源
  • GitLab常用操作
  • Java高频面试之集合-04
  • Nginx 开启Baise认证
  • 计算机二级MS之PPT
  • 数据库系统概论(一)详细介绍数据库与基本概念
  • 微服务概览与治理
  • 零售交易流程相关知识(top-down拆解)
  • 同步 Fork 仓库的命令
  • 网站海外推广服务/嘉兴seo外包公司费用
  • 租车网站制作/品牌宣传活动策划方案
  • html5风格网站特色/腾讯控股第三季度营收1401亿
  • 怎么找响应式网站/百度网页pc版登录
  • 获得网站后台地址/网站网络营销
  • 网站跳转到另外一个网站怎么做/好网站制作公司