文件上传-绕过/验证

文件上传验证

后缀名,类型,文件头

后缀名:黑名单,白名单

黑名单:明确不允许上传的格式后缀
asp php jsp aspx cgi war…
缺陷:如果php phtml…没有定义到后名单里,可以用这格式绕过限制
白名单:明确可以上传的格式后缀
jpg png zip rar gif …
白名单验证要更安全

文件类型:MIME信息

Content-Type称之为MIME信息

在这里插入图片描述

文件头:内容头信息

在这里插入图片描述

在这里插入图片描述

相关知识

onsubmit 事件

onsubmit 事件会在表单中的确认按钮被点击时发生

getElementsByName类型

document.getElementsByName(‘upload_file’)[0].value
数组的第一个值
因为很多情况下name都有可能相等,所以会有个数组来定义

var类型

var在JavaScript中是一种动态类型、弱类型、基于原型的语言,内置支持类型。

substring() 函数

方法用于提取字符串中介于两个指定下标之间的字符
2个参数,从第一个参数索引到第二个参数索引之间子串,第二个参数可选,若不选,则默认为从第一个参数索引开始到最后的子串

file.lastIndexOf(".")函数

找出最后一个.所在的索引值

allow_ext.indexOf(ext_name)函数

allow_ext.indexOf(ext_name) == -1
返回指定字符串在字符串集中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1

substr(string,start,length)
反正string中从start开始到start+length-1的子串

function deldot($s)函数

{//从末尾开始搜索,1.php.返回1.php,1.php.p.返回1.php.p

	for($i = strlen($s)-1;$i>0;$i--){
		$c = substr($s,$i,1);
		if($i == strlen($s)-1 and $c != '.'){
			return $s;
		}
		if($c != '.'){
			return substr($s,0,$i+1);
		}
	}
}

PHP strrchr(a,b) 函数

搜索 “b” 在字符串中的位置,并返回从该位置到字符串结尾的所有字符。

stripos() 函数

查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
在这里插入图片描述

getimagesize()函数

获取文件大小

php basename函数

<?php
$path = "/testweb/home.php";

//显示带有文件扩展名的文件名
echo basename($path);

//显示不带有文件扩展名的文件名
echo basename($path,".php");
?> 

输出

home.php
home

PHP pathinfo() 函数

演示案例:uploadlabs关卡分析

简要上传表单代码分析解释
在这里插入图片描述

在这里插入图片描述

less-1

在这里插入图片描述
黑盒测试
尝试上传php文件,发现只能是.jpg,.png.gif格式的文件
在这里插入图片描述
上传1.jpg(非图片内容,图片后缀文件)成功,且通过弹窗得出是白名单过滤
所以我们要想办法修改后缀使得在服务器中呈现的是php文件
首先我们上传后门文件1.php提交后抓包查看下内容
在这里插入图片描述
看到有个属性filename,尝试修改后缀为php提交
成功上传webshell

第二种方法:
禁用js绕过验证

less-2

上传php文件
在这里插入图片描述

上传1.jpg(非图片内容,图片后缀文件)成功,且通过弹窗得出是白名单过滤
可以通过第一种方法绕过
或者上传1.php抓包修改数据包的MIME为jpg
在这里插入图片描述

less1和less2的区别
less1是通过js验证后才提交表单,所以我们可以通过修改后缀为jpg,让他先通过js验证,然后再在抓包修改表单中的filename的名字,也就是文件名得以绕过

less2是通过表单验证,也就是前端会得到修改后的数据包才会进行验证,所以我们有两次方式绕过。
1、上传jpg文件,因为点击上传抓包后,出现的Content-Type默认为image/jpeg,所以我们修改filename为我们想要的文件名即可。
2、通过查看代码,发现是通过Content-Type进行验证的,所以我们可以上传php文件,将Content-Type的值改为白名单里面的值即可成功绕过。

less3

在这里插入图片描述
显示不能上传这类后缀文件,所以是黑名单过滤,所以我们可以尝试修改下后缀名为php5,上传成功。在upload文件中查看,发现其还改了文件名。

能够解析php5前提是apache的httpd.conf中有如下配置代码
AddType application/x-httpd-php .php .phtml .phps .php5 .pht

less4

常规操作后发现上面的方法都不行,所以应该检查的是filename所以我们要想办法绕过filename

查看源码发现

$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");

这一次还是黑名单,但是黑名单加多了,几乎过滤了各种后缀,但是没有过滤.htaccess。 首先上传.htaccess,文件内容为AddType application/x-httpd-php .ppp,然后上传ppp文件,就会被解析成php
.htaccess还可以写成:

<FilesMatch "shell.ppp">
  SetHandler application/x-httpd-php
</FilesMatch>

这样文件名为shell.ppp就会被解析成php。

less5

做法类似.htaccess,上传一个写有auto_prepend_file=1.jpg为后缀的.user.ini文件,然后在上传一个写有一句话木马的jpg文件,上传成功后,蚁剑连接,但是要注意,题目提示上传目录存在php文件(readme.php),所以上传成功后我们应该访问readme.php

注意:
.htaccess可以覆盖apache的配置文件,而.user.ini则可以覆盖php.ini的配置。
.htaccess文件只能用于apahce,不能用于iis和nginx等中间件
.user.ini只能用于Server API为FastCGI模式下,而正常情况下apache不是运行在此模块下的。
.htaccess和.user.ini都只能用于访问本目录下的文件时进行覆盖。
在这里插入图片描述

less6

这题还是后缀黑名单过滤,也过滤了.htaccess和.ini,但是没有将文件后缀名转换为小写,故大写绕过即可。
在这里插入图片描述

less7

查看源码,发现少了:

$file_ext = trim($file_ext); //收尾去空

这样我们可以在文件名后缀最后面加上空格,来绕过黑名单的过滤。

在这里插入图片描述

less8

查看源码,少了:

$file_name = deldot($file_name);//删除文件名末尾的点

少了对点的过滤,因此直接在文件名后缀后面加上.即可。
在这里插入图片描述
注意:.php ,.php.都会在win里面自动解析为.php

less9

查看代码发现少了
在这里插入图片描述
:: D A T A 作 用 : p h p 在 w i n d o w s 中 如 果 文 件 名 + " : : DATA作用:php在windows中如果文件名+":: DATAphpwindows+"::DATA"会把:: D A T A 之 后 的 数 据 当 成 文 件 流 处 理 , 不 会 检 测 后 缀 名 . 且 保 持 " : : DATA之后的数据当成文件流处理,不会检测后缀名.且保持":: DATA,."::DATA"之前的文件名(Windows文件流特性)
上传一句话木马的.php后缀文件,抓包加::$DATA,上传成功

less10

首先需要了解deldot函数,当deldot函数检测到末尾的第一个点时将继续从后向前检测,当检测到空格时就停下来,因此当后缀是php.[空格].时,经过deldot函数过滤后,后缀变成php.[空格],最终绕过黑名单,且上传上去的文件名为php.,在windows下会自动去除点。
在这里插入图片描述

less11

f i l e n a m e = s t r i r e p l a c e ( file_name = str_ireplace( filename=strireplace(deny_ext,"", $file_name);很明显是双写绕过,str_ireplace()函数的作用如下:

把字符串 “Hello world!” 中的字符 “WORLD”(不区分大小写)替换成 “Shanghai”:

<?php
echo str_ireplace("WORLD","Shanghai","Hello world!");
?>

抓包,把.php后缀改为.pphphp,成功绕过

less12

发现双写绕过不行了
查看代码发现多了一行代码

 $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);

这行代码是找到后缀名然后进行检查是否在白名单里
所以我们可以进行00截断
截断条件:
1、php版本小于5.3.4
2、php.ini的magic_quotes_gpc为OFF状态

原理
url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束

使用情况
上传时路径可控,使用00截断
文件下载时,00截断绕过白名单检查
文件包含时,00截断后面限制(主要是本地包含时)
其它与文件操作有关的地方都可能使用00截断。

分析

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

构造sava_path=/upload/1.php%00绕过
在这里插入图片描述

然后访问1.php即可

less13

跟less12的方法类型,不过这个是post提交,POST不会像GET那样对%00进行自动解码,因此,我们需要在burp中选中%00右击->url->urldecode go即可。

在这里插入图片描述

less14

制作文件马
方法一
1.准备一张图片1.jpg,准备一句话php木马1.php
2.通过控制台cmd命令制造图片马
3.进入两个文件的文件夹打开控制台输入命令: copy 1.php/b+1.jpg 2.jpg
4.命令解释:

使用CMD制作一句话木马。
参数/b指定以二进制格式复制、合并文件; 用于图像类/声音类文件
参数/a指定以ASCII格式复制、合并文件。用于txt等文档类文件
copy 1.jpg/b+1.php 2.jpg 
//意思是将1.jpg以二进制与1.php合并成2.jpg
那么2.jpg就是图片木马了。

方法二
1.打开010editor
2.以十六进制的方式打开1.jpg
3.在最后末尾加上一句话木马代码
在这里插入图片描述
4.保存即可
或者用notepad++也是可以的
上传照片即可然后打开路径
效果:
在这里插入图片描述
验证机制

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2单元(即2个16进制)
    fclose($file);
    $strInfo = @unpack("C2chars", $bin); //用unpack将16进制转化为有符号的2进制
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);   //把两个chars连接起来再用intval转换为整数型    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

验证机制是获取文件头的内容头信息
jpg的文件头的内容头信息是FFD8FFE1
读2个单元FF和D8
转为2进制就是255,216,连起来就是255216,为jpg文件,通过验证

less15

图片马制作是一样的
验证机制

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename); //获取图片信息
        $ext = image_type_to_extension($info[2]); //获取图片后缀
        if(stripos($types,$ext)>=0){ //如果属于$types中的一个
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

less16

验证机制

function isImage($filename){
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}

exif_imagetype() 读取一个图像的第一个字节并检查其签名。如果发现了恰当的签名则返回一个对应的常量,否则返回 FALSE。返回值跟getimagesize() 返回的数组中的索引 2 的值是一样的,但exif_imagetype函数快得多。

less17(待测试)

发现图片马上传后,里面的php代码给过滤掉了,上传只有php代码的jpg文件后提示文件错误
参考

less18

这里先将文件上传到服务器,然后通过rename修改名称,如果检查到不是合法文件后缀名,再通过unlink删除文件,因此可以通过条件竞争的方式,也就是不断查看上传后的文件,在unlink之前,访问webshell。
原理:
在查看文件的期间,服务器检测后发现是php文件,想要删除,但是用户正在查看此文件是无法删除的。
首先在burp中不断发送上传webshell的数据包:
在这里插入图片描述
在这里插入图片描述

然后不断在浏览器中访问,发现通过竞争可以访问到:
在这里插入图片描述

less19(待测试)

同18做法

less20

上传文件和文件名可控,且文件名是黑名单限制。
在这里插入图片描述

原理:
文件名改为19.php/.,move_uploaded_file函数遇到/.的时候会删除它

less 21

PHP reset函数
输出数组中的当前元素和下一个元素的值,然后把数组的内部指针重置到数组中的第一个元素

过滤机制对MIME和文件后缀都进行了检查。 但是取后缀的时候判断 f i l e 是 不 是 数 组 , 可 以 让 file是不是数组,可以让 filefile为数组来绕过

$file = explode('.', strtolower($file));

最后上传的时候文件名取的是

$file_name = reset($file) . '.' . $file[count($file) - 1];

综上,$file数组[“20.php”,"",“jpg”],最后一个为jpg可以绕过白名单检查,文件名为:20.php.,再配合move_uploaded_file的特性,最终上传的文件名为20.php。

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值