【文件上传绕过】——后端检测_文件名检测00截断绕过

一、实验目的:

1、通过本次实验掌握00截断的原理。
2、通过upload-labs-master闯关游戏Pass-11Pass-12,掌握00截断绕过技术。

二、工具:

BurpSuite
火狐/谷歌浏览器

三、实验环境:

靶 机: windows10虚拟机:192.168.100.150
      upload-labs-master闯关游戏
      phpstudy2018搭建网站

攻击机: 物理机

四、截断上传条件:

1. 关闭magic_quotes_gpc魔术函数

magic_quotes_gpc魔术函数的作用就是将我们输入的敏感字符进行自动转义。

2. PHP版本(<5.3):

切换php版本:


注:通过上面的设置后需要重启phpstudy2018。

3. 系统环境:

  如果 windows10虚拟机里面的环境无法使用,可以偿试在物理面里面进行实验,或者在windows2008中实验。

五、漏洞说明:

  虽然web应用做了校验,但是由于文件上传后的路径用户可以控制,攻击者可以利用手动添加字符串标识符0X00的方式来将后面的拼接的内容进行截断,导致后面的内容无效,而且后面的内容又可以帮助我们绕过黑白名单的检测。

六、绕过思路:

  在C语言中,空字符有一个特殊含义,代表字符串的拼接结束。
  这里我们使用的是php语言,属于高级语言,底层靠C语言来实现的,也就是说空字符的字符串拼接结束功能在PHP中也能实现。但是我们在URL中不能直接使用,这样会造成无法识别;我们通过查看ASCII对照表,发现ASCII对照表第一个就空字符,它对应的16进制是00,这里我们就可以用16进制的00来代替空字符,让它截断后面的内容。
  点击进入:ASCII对照表

七、实验过程:

1. GET请求方式绕过

1.1 upload-labs闯关游戏(Pass-11):

页面源码:

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){   //接收上传的图片;
    $ext_arr = array('jpg','png','gif'); //声明一个数组,里面有'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 = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;  //进行构造上传后的文件存储路径; 
        /*
        $_GET['save_path'] 通过GET的请求方式获得文件路径;通过这种方式获得的文件路径是用户可控的;
        .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类型文件!";
    }
}

通过上面源码可以看出,这里的上传路路径是用户可控的;这关主要看$_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;中的$_GET['save_path']请求, 是通过GET的请求方式获得文件上传后的存储路径,然后通过URL的方式传递到后台;通过这种方式获得的文件路径是用户可控的。

1、创建一个文本文件,并给它重命名为1.jpg,重命名是为了让它通过白名单的检测:
内容:

<?php phpinfo(); ?>

2、 上传2.jpg文件:


3、使用burpsuite进行抓包,因为这里是通过URL进行传递的文件上传后存储路径,所以需要对16进制00进行URL编码,编码的结果就是%00,通过这种方式,就可以%00截断后面的内容,让拼接的文件名不再进行生效:


4、右击,复制图片地址,进行访问时,发现文件未找到:

5、需要删除php后面的内容,再进行访问,可以正常进行解析:

1.2 没有对文件名进行重构的截断上传方法:

1、修改文件为*.jpg
2、使用burpsuite进行抓包,修改文件名为:*.php%00.jpg
文件上传后的存储路径相当于:$img_path=../upload/*.php%00.jpg

2. POST请求方式绕过

2.1 upload-labs闯关游戏(Pass-12):

页面源码:

$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类型文件!";
    }
}

1、上传一个1.jpg的文件,重命名是为了让它通过白名单的检测:

2、使用burpsuite进行抓包,修改为%00发现上传文件失败:


注:出现这个问题的原因是因为前面Pass11是通过GET请求方式获得的文件上传路径,而GET请求方式是通过URL进行传输数据的,需要进行URL编码%0016进制进行URL编码后的结果;而Pass12POST请求方式,不是通过URL进行传输数据,所以不用进行URL编码,使用URL编码后截断就会导致上传失败。

3、通过下面的方式对%00进行URL解码,并发送数据:



4、发现可以正常进行上传,复制图片地址,并进行访问,删除php后面的内容后,发现可以正常解析:


  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文件上传漏洞是一种常见的Web安全漏洞,攻击者通过绕过文件头检测机制,上传恶意文件到服务器上,从而执行任意代码或者获取敏感信息。文件头绕过是指攻击者通过修改文件的内容或者文件名来欺骗服务器的文件类型检测机制,使得服务器无法正确判断文件的真实类型。 为了绕过文件头检测机制,攻击者可以采取以下几种方法: 1. 修改文件内容:攻击者可以在文件的开头添加一些特殊字符或者修改文件的二进制内容,使得文件头部的标识符不再符合服务器的文件类型检测规则。 2. 修改文件扩展名:攻击者可以将恶意文件的扩展名修改为服务器允许上传的合法文件类型的扩展名,从而欺骗服务器认为该文件是合法的。 3. 使用双重扩展名:攻击者可以将恶意文件的扩展名修改为两个或多个扩展名的组合,例如将`.php`文件修改为`.jpg.php`,这样服务器可能只会检测到第一个扩展名,从而误判文件类型。 4. 使用特殊编码:攻击者可以使用特殊编码对文件进行编码,使得文件头部的标识符被隐藏或者混淆,从而绕过文件类型检测。 为了防止文件上传漏洞的文件头绕过,开发者可以采取以下几种措施: 1. 文件类型检测:在服务器端对上传的文件进行类型检测,可以通过检查文件的魔术数字、文件扩展名、MIME类型等方式来判断文件的真实类型。 2. 文件名过滤:对上传的文件名进行过滤,只允许合法的文件名字符,避免使用特殊字符或者路径分隔符。 3. 文件内容检测:对上传的文件内容进行检测,可以通过解析文件内容或者使用杀毒软件等方式来检测文件是否包含恶意代码。 4. 文件权限设置:限制上传文件的存储路径的访问权限,避免攻击者通过上传恶意文件获取服务器的敏感信息或者执行任意代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值