早睡早起,方能养生
Sleep early rise early, way to keep healthy

PHP下载图片,文件

super
2021-09-20 15:42
views 2723

结合一篇WebShell文章, 写的文件下载。

 

if (!function_exists('download_file')) {
    /**
     * PHP下载图片 防止图片注入版
     * @author super
     * @time 2021-09-20 11:25:19
     * @param string $link 外部文件链接
     * @param string $save_path 保存文件夹. 下载地址在 根目录/download/$save_path
     * @param array $verify 验证规则及常规配置
     * @return array
     * */
    function download_file($link, $save_path = 'base', $verify = ['type' => 'image', 'save_suf' => 'png'])
    {
        // 判断路径中是否存在.php .asp .aspx .jsp   // xxx.php.png
        $dangerFileExt = [
            '.php',
            '.asp',
            '.aspx',
            '.jsp',
        ];
        foreach ($dangerFileExt as $v) {
            if (strpos($link, $v)) {
                return ['code' => 500, 'msg' => '下载错误,网络繁忙!'];
            }
        }
        $headers = get_headers($link,  1);
        if ($headers['Content-Type'] == 'binary/octet-stream' || $headers['Content-Type'] == 'application/octet-stream') {
            // 尝试上传木马文件,建议在此封禁IP
            return ['code' => 500, 'msg' => '下载错误,网络繁忙!'];
        }
        // 识别文件

        $ext = [
            'image' => [
                'title' => '图片',
                'ext' => [
                    'image/png',
                    'image/jpeg',
                    // 'image/gif'
                    // ...
                ]
            ], 
            // ...
        ];

        // https://www.iana.org/assignments/media-types/media-types.xhtml
        $set_ext = $ext[$verify['type']];
        if (isset($set_ext)) {
            if (!in_array($headers['Content-Type'], $set_ext['ext'])) {
                return ['code' => 500, 'msg' => "未获取到" . $set_ext['title'] . ", 请检查" . $set_ext['title'] . "地址是否正确!"];
            }
        }

        // 下载文件
        $header = [
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'Accept-Encoding: gzip, deflate, br',
            'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8',
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
        ];
        $curl = curl_init();
        // 设置抓取的url
        curl_setopt($curl, CURLOPT_URL, $link);
        // 设置头文件的信息作为数据流输出
        curl_setopt($curl, CURLOPT_HEADER, false);
        // 超时设置,以秒为单位
        curl_setopt($curl, CURLOPT_TIMEOUT, 1);
    
        // 超时设置,以毫秒为单位
        // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
    
        // 设置请求头
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        // 设置获取的信息以文件流的形式返回,而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        // 执行命令
        $data = curl_exec($curl);
        $error = curl_error($curl);
        curl_close($curl);
    
        // 显示错误信息
        if ($error) {
            // print "Error: " . $error;
            return ['code' => 500, 'msg' => '下载错误,网络繁忙!'];
        }
        
        $file_name = create_file_name('/download/' . $save_path . '/', $verify['save_suf']);

        $f = fopen('.' . $file_name, 'w+');
        fwrite($f, $data);
        fclose($f);

        // 识别文件
        switch ($verify['type']) {
            case 'image':
                $analysis = getimagesize('.' . $file_name);
                if ($analysis == false) {
                    unlink('.' . $file_name);
                    return ['code' => 500, 'msg' => '下载失败, 没有找到有效的图像格式!'];
                }
                break;
            default:
                // code...
                break;
        }
        return ['code' => 200, 'path' => $file_name];
    }

    function create_file_name($save_path, $suf)
    {
        if (!file_exists('.' . $save_path)) {
            mkdir('.' . $save_path, 0777, true);
        }
        $file_name = md5(time() . rand(1000, 9999));
        $path = $save_path . $file_name . '.' . $suf;
        if (!file_exists('.' . $path)) {
            return $path;
        }
        return create_file_name($save_path, $suf);
    }
}


分享
0 条讨论
top