upload-labs

upload-labs学习过程

*所有上传的文件在upload目录下

Pass-1

过滤方法 绕过方法
前端JS过滤 禁用JS、抓包上传

源码分析

function checkFile() {
    //判断上传文件类型是否允许上传
    if (不是.jpg|.png|.gif后缀) {
        return false;
    }
}
  • 这是在前端进行过滤,如果上传的文件不是jpg/png/gif文件,就返回错误

有两种方法绕过

1.禁用JS

禁用方法自行百度

原理:JS被禁用后,前端判断上传文件类型的代码失效

2.抓包上传

先将要上传的文件后缀改为允许上传的类型,再用burpsuite抓包,重新修改后缀即可

Pass-2

过滤方法 绕过方法
MIME白名单过滤 抓包修改MIME类型

源码分析

if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')):
    上传文件
else:
    报错

本pass在服务端对数据包的MIME进行检查,我们可以抓包修改Content-Type:字段为image/png来绕过

Pass-3

过滤方法 绕过方法
后缀名黑名单过滤 php3绕过黑名单

源码分析

//黑名单
$deny_ext = array('.asp','.aspx','.php','.jsp');

if(所上传的文件后缀不在黑名单):
    上传文件
else:
    报错

黑名单过滤了php文件,但是我们可以上传php3、phtml类型的文件,还是可以解析成php文件

我上传成功但是没办法打开php3文件,不知道为什么

Pass-4

过滤方法 绕过方法
后缀名黑名单过滤 重写文件解析规则

这一关过滤的黑名单有点长,看图

虽然过滤了很多,但是没有过滤 .htaccess,新建一个.htaccess的文件,写入以下内容

SetHandler application/x-httpd-php

然后上传,这样该目录的文件都可以解析成php,可以上传.jpg为后缀的php脚本来绕过检测,到时候会被解析成php

Pass-5

过滤方法 绕过方法
后缀名黑名单过滤 .user.ini

源码分析

$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); //首尾去空

发现过滤了很多后缀,包括.htaccess,还将文件后缀名转换为小写

.user.ini

  • 先上传一个以auto_prepend_file=test.gif为内容的.user.ini文件,.user.ini文件里面的意思是:所有的php文件都自动包含test.gif文件。auto_prepend_file作用是为了避免多数文件都需要引入一个相同的文件,而反复的 include

  • 然后再上传一个内容为<?php phpinfo();?>的一句话的脚本,命名为test.gif

  • 因为原来的上传目录里面就已经有了一个readme.php的文件,所以我们不是上传了php文件,而是在已存在的PHP文件写入了一句话木马

Pass-6

过滤方法 绕过方法
后缀名黑名单过滤 大小写绕过

分析源码

$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); //首尾去空

过滤方法基本和Pass-5相同,但是少了strtolower(),所以可以利用后缀名大小写绕过

大小写绕过原理:

Windows系统下,对于文件名中的大小写不敏感。例如:test.php和TeSt.PHP是一样的。 Linux系统下,对于文件名中的大小写敏感。例如:test.php和 TesT.php就是不一样的。

我遇到的问题

我是用bp抓包修改大小写,但是访问的时候却500,查了很久也没找到原因,希望有大佬指点一下

Pass-7

过滤方法 绕过方法
后缀名黑名单过滤 空格绕过

源码分析

$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 = $_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

过滤了差不多,但是少了trim()过滤,它的作用是移除字符串首尾的空格,所以这里可以使用空格绕过

空格绕过原理

在Windows下,对于文件名中空格会被作为空处理,但程序中的检测代码却不能自动删除空格。从而绕过黑名单。

我遇到的问题

bp抓包在文件名最后添加空格,但是却显示上传失败,也找不到原因

Pass-8

过滤方法 绕过方法
后缀名黑名单过滤 点绕过

源码分析

$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_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

过滤了差不多,但是少了deldot()过滤,它的作用是移除字符串最后的点,所以这里可以使用点绕过

原理

假如上传的文件名是1.php.,后端代码过滤时获取的文件后缀名时.而不是.php.,这样就会绕过检测

而Windows系统下,文件后缀名最后一个点会被自动去除,这样我们上传的文件到服务区上就变成了1.php

Pass-9

过滤方法 绕过方法
后缀名黑名单过滤 点绕过

源码分析

$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 = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空

过滤了差不多,但是忘记过滤::$DATA,所以这里可以使用::$DATA绕过,这属于特殊符号绕过

特殊符号绕过原理

在Windows系统下,上传文件名为test.php::$DATA的文件会在服务器上变为test.php,因为Windows下文件名中不能有特殊符号

Pass-10

过滤方法 绕过方法
后缀名黑名单过滤 点绕过

源码分析

$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 = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
  • 发现该过滤的都过滤了,但还是可以利用deldot()函数

deldot()函数只能删掉字符串最后一个点,如果文件名最后有两个点呢?删一个点还剩一个点,然后就跟Pass-8一个样子了

上传1.php..deldot()函数处理后变成1.php.,后端代码获取文件后缀名时得到的就是.,这样就绕过了检测


文章作者: MissPower007
文章链接: http://time.pings.fun
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 MissPower007 !
评论
  目录