浅谈常见的文件上传的检测方式与绕过方法
字数 2005 2025-08-26 22:12:02

文件上传漏洞检测与绕过技术详解

前言

文件上传漏洞是渗透测试中最直接有效的攻击方式之一,攻击者通过上传恶意文件可直接获取webshell。本文将全面分析常见的文件上传检测机制及相应的绕过方法。

前端检测与绕过

JavaScript检测

检测原理
前端通过JavaScript验证文件扩展名,通常检查文件后缀是否在白名单内。

示例代码

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

绕过方法

  1. 使用Burp Suite等工具拦截并修改上传请求
  2. 直接禁用浏览器JavaScript功能
  3. 修改前端HTML代码移除验证逻辑

后端检测与绕过

1. 文件类型检测

1.1 检测Content-Type

检测原理
检查HTTP请求头中的Content-Type字段,如image/jpegimage/png等。

示例代码

$allow_content_type = array("image/gif", "image/png", "image/jpeg");
$type = $_FILES["myfile"]["type"];
if (!in_array($type, $allow_content_type)) {
    die("File type error!<br>");
}

绕过方法

  • 拦截请求修改Content-Type为允许的类型(如image/jpeg

1.2 检测文件头

检测原理
使用getimagesize()等函数读取文件真实类型,检查文件头标志。

常见文件头

  • GIF: 47 49 46 38 39 61 (GIF89a)
  • JPEG: FF D8 FF
  • PNG: 89 50 4E 47 0D 0A

示例代码

$allow_mime = array("image/gif", "image/png", "image/jpeg");
$imageinfo = getimagesize($_FILES["myfile"]["tmp_name"]);
if (!in_array($imageinfo['mime'], $allow_mime)) {
    die("File type error!<br>");
}

绕过方法

  • 使用十六进制编辑器在恶意文件前添加图片文件头
  • 制作图片马(将代码插入图片元数据中)

2. 文件扩展名检测

2.1 黑名单检测

检测原理
禁止特定危险扩展名(如php、asp、jsp等)的文件上传。

示例代码

$blacklist = array('php', 'asp', 'aspx', 'jsp');
$type = array_pop(explode('.', $_FILES['myfile']['name']));
if (in_array(strtolower($type), $blacklist)) {
    die("File type errer!<br>");
}

绕过方法

  1. 使用替代扩展名:
    • PHP: .php3, .php4, .php5, .phtml
    • ASP: .asa, .cer, .cdx
    • JSP: .jspx
  2. 大小写混淆:.pHp, .AsP
  3. 特殊字符:
    • 空格:shell.php
    • 点号:shell.php.
    • ::$DATAshell.php::$DATA
  4. 双扩展名:shell.jpg.php

2.2 白名单检测

检测原理
只允许特定安全扩展名(如jpg、png等)的文件上传。

示例代码

$whitelist = array('png', 'jpg', 'jpeg', 'gif');
$type = array_pop(explode('.', $_FILES['myfile']['name']));
if (!in_array(strtolower($type), $whitelist)) {
    die("File type errer!<br>");
}

绕过方法

  1. 结合%00截断(需PHP<5.3.4且magic_quotes_gpc关闭)
  2. 利用服务器解析漏洞
  3. 上传图片马配合文件包含漏洞
  4. 上传.htaccess文件控制解析规则

3. 文件内容检测

3.1 内容替换过滤

检测原理
替换文件内容中的危险字符(如PHP标签<?)。

示例代码

$content = file_get_contents($_FILES['myfile']['tmp_name']);
$content = str_replace('?', '!', $content);
file_put_contents($file, $content);

绕过方法

  • 使用替代PHP标签:<script language='php'>system('ls');</script>
  • 使用短标签:<?= system('ls'); ?>(需short_open_tag开启)

3.2 图片二次渲染

检测原理
使用GD库等重新生成图片,过滤嵌入的恶意代码。

示例代码

$im = imagecreatefromjpeg($target_path);
imagejpeg($im,$img_path);

绕过方法

  1. 将代码插入图片EXIF等元数据区域
  2. 使用特定工具生成绕过二次渲染的图片马(如jpg_payload.php)

服务器解析漏洞利用

1. IIS解析漏洞

IIS 6.0

  1. 目录解析:/xxx.asp/1.jpg(xxx.asp目录下的所有文件都作为ASP解析)
  2. 分号解析:test.asp;.jpg(被当作ASP文件解析)

IIS 7.0/7.5

  • PHP CGI解析漏洞:http://test.com/a.jpg/.php(需cgi.fix_pathinfo=1)

2. Apache解析漏洞

扩展名解析特性

  • 从右向左解析:a.php.xxx(xxx不可识别,向左识别为php)
  • 可绕过黑名单检测

CVE-2017-15715

  • 上传文件名包含换行符:a.php\x0A
  • 可绕过黑名单正则匹配

3. %00截断

利用条件

  • PHP < 5.3.4
  • magic_quotes_gpc关闭

示例

$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
// 传入save_path="../upload/shell.php%00"

绕过方法

  • POST传参:使用Burp Suite修改hex值为00或URL解码%00
  • GET传参:直接传入%00(浏览器自动URL解码)

4. .htaccess利用

利用条件

  • Apache配置AllowOverride All
  • 可上传.htaccess文件

配置方式

  1. 指定文件名解析:
<FilesMatch "test">
  SetHandler application/x-httpd-php
</FilesMatch>
  1. 指定扩展名解析:
AddType application/x-httpd-php .jpg

防御建议

  1. 使用白名单而非黑名单
  2. 文件重命名(避免用户控制文件名)
  3. 限制上传目录执行权限
  4. 检查文件真实类型(MIME+扩展名+内容)
  5. 对上传文件进行病毒扫描
  6. 及时更新服务器软件修补解析漏洞

总结

文件上传漏洞的检测与绕过是攻防对抗的典型场景,实际环境中往往需要结合多种技术手段。渗透测试时应先进行充分的信息收集,了解服务器环境、脚本语言版本等,再选择适当的绕过方法。防御方则应采取多层次防护措施,避免单一检测机制被绕过。

文件上传漏洞检测与绕过技术详解 前言 文件上传漏洞是渗透测试中最直接有效的攻击方式之一,攻击者通过上传恶意文件可直接获取webshell。本文将全面分析常见的文件上传检测机制及相应的绕过方法。 前端检测与绕过 JavaScript检测 检测原理 : 前端通过JavaScript验证文件扩展名,通常检查文件后缀是否在白名单内。 示例代码 : 绕过方法 : 使用Burp Suite等工具拦截并修改上传请求 直接禁用浏览器JavaScript功能 修改前端HTML代码移除验证逻辑 后端检测与绕过 1. 文件类型检测 1.1 检测Content-Type 检测原理 : 检查HTTP请求头中的Content-Type字段,如 image/jpeg 、 image/png 等。 示例代码 : 绕过方法 : 拦截请求修改Content-Type为允许的类型(如 image/jpeg ) 1.2 检测文件头 检测原理 : 使用 getimagesize() 等函数读取文件真实类型,检查文件头标志。 常见文件头 : GIF: 47 49 46 38 39 61 (GIF89a) JPEG: FF D8 FF PNG: 89 50 4E 47 0D 0A 示例代码 : 绕过方法 : 使用十六进制编辑器在恶意文件前添加图片文件头 制作图片马(将代码插入图片元数据中) 2. 文件扩展名检测 2.1 黑名单检测 检测原理 : 禁止特定危险扩展名(如php、asp、jsp等)的文件上传。 示例代码 : 绕过方法 : 使用替代扩展名: PHP: .php3 , .php4 , .php5 , .phtml ASP: .asa , .cer , .cdx JSP: .jspx 大小写混淆: .pHp , .AsP 特殊字符: 空格: shell.php 点号: shell.php. ::$DATA : shell.php::$DATA 双扩展名: shell.jpg.php 2.2 白名单检测 检测原理 : 只允许特定安全扩展名(如jpg、png等)的文件上传。 示例代码 : 绕过方法 : 结合%00截断(需PHP<5.3.4且magic_ quotes_ gpc关闭) 利用服务器解析漏洞 上传图片马配合文件包含漏洞 上传.htaccess文件控制解析规则 3. 文件内容检测 3.1 内容替换过滤 检测原理 : 替换文件内容中的危险字符(如PHP标签 <? )。 示例代码 : 绕过方法 : 使用替代PHP标签: <script language='php'>system('ls');</script> 使用短标签: <?= system('ls'); ?> (需short_ open_ tag开启) 3.2 图片二次渲染 检测原理 : 使用GD库等重新生成图片,过滤嵌入的恶意代码。 示例代码 : 绕过方法 : 将代码插入图片EXIF等元数据区域 使用特定工具生成绕过二次渲染的图片马(如jpg_ payload.php) 服务器解析漏洞利用 1. IIS解析漏洞 IIS 6.0 目录解析: /xxx.asp/1.jpg (xxx.asp目录下的所有文件都作为ASP解析) 分号解析: test.asp;.jpg (被当作ASP文件解析) IIS 7.0/7.5 PHP CGI解析漏洞: http://test.com/a.jpg/.php (需cgi.fix_ pathinfo=1) 2. Apache解析漏洞 扩展名解析特性 从右向左解析: a.php.xxx (xxx不可识别,向左识别为php) 可绕过黑名单检测 CVE-2017-15715 上传文件名包含换行符: a.php\x0A 可绕过黑名单正则匹配 3. %00截断 利用条件 : PHP < 5.3.4 magic_ quotes_ gpc关闭 示例 : 绕过方法 : POST传参:使用Burp Suite修改hex值为00或URL解码%00 GET传参:直接传入%00(浏览器自动URL解码) 4. .htaccess利用 利用条件 : Apache配置AllowOverride All 可上传.htaccess文件 配置方式 : 指定文件名解析: 指定扩展名解析: 防御建议 使用白名单而非黑名单 文件重命名(避免用户控制文件名) 限制上传目录执行权限 检查文件真实类型(MIME+扩展名+内容) 对上传文件进行病毒扫描 及时更新服务器软件修补解析漏洞 总结 文件上传漏洞的检测与绕过是攻防对抗的典型场景,实际环境中往往需要结合多种技术手段。渗透测试时应先进行充分的信息收集,了解服务器环境、脚本语言版本等,再选择适当的绕过方法。防御方则应采取多层次防护措施,避免单一检测机制被绕过。