web安全-文件上传基础知识-php原码相关知识-upload靶场下载及搭建详细教程-upload靶场通关必备工具的下载安装以及使用的详细教程-upload靶场通关详细教学(1)

一、文件上传常见的验证类型

包括:后缀名,类型,文件头等。

1.后缀名(直接验证):黑名单,白名单;

黑名单:明确不让上传的格式后缀
asp php jsp aspx cgi war...

白名单:明确可以上传的格式后缀
jpg png zip rar gif...

白名单相对比黑名单更加安全一些,
因为黑名单可能存在漏写的情况,
而白名单则只允许上传白名单内存在的后缀。

2.文件类型(间接验证):MIME(Content-Type值);

通过后缀名和文件类型的联系,
通过文件类型来猜测后缀名,
这种方法并不严谨,
因为可以通过抓包进行二次修改来伪造。

上传gif格式文件

上传jsp格式文件

3.文件头(间接验证):内容头信息;

通过文件头信息和文件类型的联系,
通过文件头信息来猜测后缀名,
这种方法并不严谨,
因为可以通过抓包进行二次修改来伪造。

打开两个png后缀的图片,可以看到最开始的部分都是相同的。

打开两个jif后缀的图片,可以看到最开始的部分都是相同的。

二、了解原码相关内容

1.“$_FILES”相关内容

其中['myFile']是表单里的参数名的值

  • $_FILES['myFile']['name']

客户端文件的原名称。

  • $_FILES['myFile']['type']

文件的MIME类型,需要浏览器提供该信息的支持,例如"image/gif"。

  • $_FILES['myFile']['size']

已上传文件的大小,单位为字节。

  • $_FILES['myFile']['tmp_name']

文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload _tmp_dir指定,但用putenv()函数设置是不起作用的。

2.实例解释

首先写一份如下图所示的原码(“action”设置为空,将上传提交给当前文件)。

访问网页后上传一个文件查看返回内容如下。

可以利用类似如下图所示的方法来进行上传文件过滤。

3.注意

下图中框选的二者要对应一致。

4.其它

三、upload-labs靶场下载配置及必备工具

靶场简介

upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共21关,每一关都包含着不同上传方式。

靶场下载地址

https://github.com/c0ny1/upload-labs

靶场环境下载地址——phpstudy

https://www.xp.cn/download.html

靶场搭建

将靶场下载后只需解压后粘贴到WWW目录下即可。

注意:PHP版本建议使用5.2.17,否则部分Pass可能无法绕过。

靶场通关必备工具——BurpSuite

BurpSuite超详细安装教程-功能概述-配置-使用教程---(附下载链接)

四、upload-labs靶场通关教程

<Pass-01>

提示:
本pass在客户端使用js对不合法图片进行检查!

原码:
function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }
}

选中事先创建好的“php.php”文件,修改前端代码,之后点击上传。

文件内容为:
<?php
phpinfo();
?>

访问发现可以执行。

<Pass-02>

提示:
本pass在服务端对数据包的MIME进行检查!

原码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

选中事先创建好的“php.php”文件,开启代理,点击上传,使用Burp抓包修改Content-Type值(image/jpeg、image/png、image/gif)之后放包。

访问发现可以执行。

<Pass-03>+php后缀常见别名

提示:
本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!

原码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $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 . '文件夹不存在,请手工创建!';
    }
}

此关采用的是黑名单拦截,因此考虑到采用php文件的其它扩展名来绕过(包括:php3、php5、phtml等)。

修改php后缀名为php3,点击上传即可绕过。


知识补充:

php后缀常见别名:.php .phtml .php3 .php5 .php1 .php4 .php2 .pht


<Pass-04>

提示:
本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!

原码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

此关与上一关的区别在于本关的黑名单包含了大多数脚本后缀名,因此上一关的办法在本关并不可行。

先上传.htaccess 文件,再上传一个文件名中包含“ranzi”的PHP代码文件。

.htaccess 文件的内容为:
<FilesMatch "ranzi">
SetHandler application/x-httpd-php
</FilesMatch>

注意:“.htaccess” 文件最好使用Notepad++创建。

命名为.htaccess这个文件是伪静态文件。

文件名中含有“ranzi”的文件用PHP代码解析执行。

<Pass-05>

提示:
上传目录存在php文件(readme.php)

原码:
$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 . '文件夹不存在,请手工创建!';
    }
}

可以看到本关内将“.htaccess”后缀名文件也进行了过滤。

先上传.user.ini。

作用域是当前文件夹和当前文件夹中的子文件;包含指定的文件,显示在页面上。

.user.ini的内容:
Auto_prepend_file=phpinfo.jpg //在页面上部显示
Auto_prepend_file=phpinfo.jpg //在页面底部部显示

再上传phpinfo.jpg。

查看readme.php文件即可。

<Pass-06>

提示:
本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!

原码:
$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",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $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 = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
缺少的代码:
$file_ext= strtolower($file_ext); //转换为小写

没有过滤大小写的代码。

所以考虑修改上传文件的后缀名为php.Php。

上传php.Php。

可以看到上传成功了,访问发现可以执行。


剩余关卡详解见下一篇文章。


  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 根据题目,机器字长为8位,因此需要用8位二进制数来表示这些数字的不同表示。 1. -1的表示: - 原码:10000001 - 反码:11111110 - 补码:11111111 - 移码:10000000 2. -1011001的表示: - 原码:11101001 - 反码:10010110 - 补码:10010111 - 移码:11101000 3. 1011001的表示: - 原码:01011001 - 反码:01011001 - 补码:01011001 - 移码:01011001 其中,原码表示是最基本的二进制表示,正数的原码与补码相同,而负数的原码最高位为1。反码是将原码中除符号位以外的位按位取反得到的。补码是将反码末位加1得到的,是计算机中负数的标准表示方式。移码是将补码中所有位数加上一个固定值得到的,在计算机中常用于浮点数的表示。 ### 回答2: -1的原码表示为:10000001 -1的反码表示为:11111110 -1的补码表示为:11111111 -1的移码表示为:01111111 -1011001的原码表示为:11010111 -1011001的反码表示为:10101000 -1011001的补码表示为:10101001 -1011001的移码表示为:00101001 1011001的原码表示为:1011001 1011001的反码表示为:1011001 1011001的补码表示为:1011001 1011001的移码表示为:0011001 设机器字长为8位,表示范围为-128 ~ 127。可以发现上述三个数目前都是负数,而负数在计算机中是用补码表示的。所以需要将这三个数的原码转换为补码来表示。 对于原码转换为补码的方法为: 如果原码的符号位为1(表示负数),则补码不变; 如果原码的符号位为0(表示正数),则补码等于原码。 对于补码转换为反码的方法为: 如果补码的符号位为1(表示负数),则反码等于补码除符号位外的位取反; 如果补码的符号位为0(表示正数),则反码等于补码。 对于补码转换为移码的方法为: 将补码的符号位取反得到移码。 因此,给出的三个数的补码和移码与原码是一样的。 ### 回答3: -1的8位原码表示为:10000001 -1的8位反码表示为:11111110 -1的8位补码表示为:11111111 -1的8位移码表示为:10000000 -1011001的8位原码表示为:11011001 -1011001的8位反码表示为:11100110 -1011001的8位补码表示为:11100111 -1011001的8位移码表示为:11111110 1011001的8位原码表示为:00110001 1011001的8位反码表示为:00110001 1011001的8位补码表示为:00110001 1011001的8位移码表示为:00110001 在8位的机器中,正数的原码、反码、补码和移码表示都相同。而负数的反码表示为对其原码除符号位外的每一位取反,补码表示为对其原码除符号位外的每一位取反,然后再加1。 移码表示是为了简化负数的运算,将其转换成的在同等位数上的正数运算。移码的规则是对补码取反得到移码,正数的移码与原码相同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ranzi.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值