记一次绕过后缀安全检查进行文件上传
字数 1092 2025-08-06 23:10:24

绕过文件后缀安全检查的上传技术分析

技术背景

在Windows系统中,当保存文件的文件名以点(.)结尾时,系统会自动将该点去掉。这一特性可以被利用来绕过某些文件上传功能的后缀安全检查,实现任意文件上传。

漏洞原理

  1. Windows文件名处理特性

    • Windows会自动去除文件名末尾的点(.)
    • 例如:上传"shell.php."会被系统存储为"shell.php"
  2. 安全检查绕过机制

    • 许多文件上传检查仅验证文件扩展名
    • 检查逻辑可能使用简单的字符串匹配或正则表达式
    • 检查"shell.php."时可能认为不是.php文件(因为有尾随点)
    • 但实际存储为"shell.php"后仍可被解析执行

攻击场景

  1. 典型应用环境

    • 使用Windows服务器的Web应用
    • 有文件上传功能且仅做简单后缀检查
    • 上传目录有脚本执行权限
  2. 检查逻辑缺陷示例

    // 不完善的检查代码
    $allowed = array('jpg', 'png', 'gif');
    $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
    if(!in_array($ext, $allowed)) {
        die('Invalid file type!');
    }
    

利用方法

  1. 基本利用

    • 准备恶意脚本文件,如PHP webshell
    • 将文件名命名为"shell.php."(注意末尾的点)
    • 上传文件
  2. 变体利用

    • "shell.php "
    • "shell.php::$DATA"
    • "shell.php\x00.jpg"
    • 其他Windows文件名特性相关的变形

防御措施

  1. 服务器端防御

    • 使用白名单验证文件类型
    • 不仅检查扩展名,还要检查文件内容
    • 重命名上传的文件
    • 设置正确的文件权限
  2. 代码示例

    // 安全的检查方式
    $allowed = array('jpg' => 'image/jpeg', 'png' => 'image/png');
    $fileinfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($fileinfo, $_FILES['file']['tmp_name']);
    
    $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
    if(!array_key_exists($ext, $allowed) || $allowed[$ext] !== $mime) {
        die('Invalid file!');
    }
    
    // 重命名文件
    $newname = md5_file($_FILES['file']['tmp_name']).'.'.$ext;
    move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$newname);
    
  3. 其他防御

    • 禁用上传目录的脚本执行权限
    • 使用单独的子域名托管用户上传内容
    • 定期审计上传的文件

实际案例

  1. 漏洞发现

    • 在文件上传功能测试时尝试上传"test.php."
    • 服务器返回上传成功
    • 实际访问时发现文件被存储为"test.php"并可执行
  2. 影响评估

    • 可能导致任意代码执行
    • 服务器完全沦陷风险
    • 数据泄露可能性

扩展知识

  1. Windows其他文件名特性

    • 保留字(CON, PRN, AUX等)
    • 文件流特性(如test.php::$DATA)
    • 长文件名处理
  2. 相关漏洞类型

    • 双扩展名绕过(如shell.php.jpg)
    • 大小写混淆(如sHell.PhP)
    • 空字节注入(如shell.php%00.jpg)
    • MIME类型欺骗

测试方法

  1. 手工测试

    • 尝试上传各种变形文件名
    • 观察服务器响应和实际存储结果
    • 验证是否可访问和执行
  2. 自动化测试

    • 使用Burp Suite等工具拦截上传请求
    • 修改文件名参数进行模糊测试
    • 检查响应差异

总结

利用Windows文件名处理特性绕过文件上传检查是一种常见且有效的攻击技术。防御此类攻击需要开发者深入理解文件系统特性,实施多层次的安全检查,而不仅仅是简单的扩展名验证。

绕过文件后缀安全检查的上传技术分析 技术背景 在Windows系统中,当保存文件的文件名以点(.)结尾时,系统会自动将该点去掉。这一特性可以被利用来绕过某些文件上传功能的后缀安全检查,实现任意文件上传。 漏洞原理 Windows文件名处理特性 : Windows会自动去除文件名末尾的点(.) 例如:上传"shell.php."会被系统存储为"shell.php" 安全检查绕过机制 : 许多文件上传检查仅验证文件扩展名 检查逻辑可能使用简单的字符串匹配或正则表达式 检查"shell.php."时可能认为不是.php文件(因为有尾随点) 但实际存储为"shell.php"后仍可被解析执行 攻击场景 典型应用环境 : 使用Windows服务器的Web应用 有文件上传功能且仅做简单后缀检查 上传目录有脚本执行权限 检查逻辑缺陷示例 : 利用方法 基本利用 : 准备恶意脚本文件,如PHP webshell 将文件名命名为"shell.php."(注意末尾的点) 上传文件 变体利用 : "shell.php " "shell.php::$DATA" "shell.php\x00.jpg" 其他Windows文件名特性相关的变形 防御措施 服务器端防御 : 使用白名单验证文件类型 不仅检查扩展名,还要检查文件内容 重命名上传的文件 设置正确的文件权限 代码示例 : 其他防御 : 禁用上传目录的脚本执行权限 使用单独的子域名托管用户上传内容 定期审计上传的文件 实际案例 漏洞发现 : 在文件上传功能测试时尝试上传"test.php." 服务器返回上传成功 实际访问时发现文件被存储为"test.php"并可执行 影响评估 : 可能导致任意代码执行 服务器完全沦陷风险 数据泄露可能性 扩展知识 Windows其他文件名特性 : 保留字(CON, PRN, AUX等) 文件流特性(如test.php::$DATA) 长文件名处理 相关漏洞类型 : 双扩展名绕过(如shell.php.jpg) 大小写混淆(如sHell.PhP) 空字节注入(如shell.php%00.jpg) MIME类型欺骗 测试方法 手工测试 : 尝试上传各种变形文件名 观察服务器响应和实际存储结果 验证是否可访问和执行 自动化测试 : 使用Burp Suite等工具拦截上传请求 修改文件名参数进行模糊测试 检查响应差异 总结 利用Windows文件名处理特性绕过文件上传检查是一种常见且有效的攻击技术。防御此类攻击需要开发者深入理解文件系统特性,实施多层次的安全检查,而不仅仅是简单的扩展名验证。