PHP下载图片,文件
super
2021-09-20 15:42
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 条讨论