File Upload

原理:将文件伪装成合法文件,然后绕过检验机制

与file inclusion结合使用

../../hackable/uploads/phpinfo.php

Low

直接上传

fu-l

$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

The basename() function returns the filename from a path.

path Required. Specifies a file path
suffix Optional. A file extension. If the filename has this file extension, the file extension will be cut off

Medium

fu-m

fu-m2

  1. Content-Type改为image/png

  2. phpinfo%20.png

->php文件的识别方式https://docs.pingcode.com/ask/ask-ask/293930.html

->浏览器执行php文件

->https://www.php.net/manual/en/features.file-upload.post-method.php $_FILES全局变量详解

常见魔数

文件类型 文件头 文件尾
JPG FF D8 FF E0 FFD9
GIF 47 49 46 38
PSD 38 42 50 53
PNG 89 50 4E 47 AE 42 60 82
GIF 47 49 46 38 00 3B
BMP 42 4D
TIFF 49 49 2A 00
ZIP 50 4B 03 04 50 4B
MS Word/Excel (xls.or.doc) D0 CF 11 E0
PDF 25 50 44 46 2D 31 2E
RAR 52 61 72 21

High

fu-h2

getimagesize( $uploaded_tmp )

1
2
3
4
5
6
7
<?php
list($width, $height, $type, $attr) = getimagesize("runoob-logo.png");
echo "宽度为:" . $width;
echo "高度为:" . $height;
echo "类型为:" . $type;
echo "属性:" . $attr;
?>

impossible

fu-im

  1. $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);

strrpos

strrpos(string $haystack, string $needle, int $offset = 0): int|false

Find the numeric position of the last occurrence of needle in the haystack string.

offset是指查找的起始位置的偏移

substr从起始位置截断字符串

  1. $target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;

    uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。

    ​ 如果 prefix 参数为空,则返回的字符串有 13 个字符串长。如果 more_entropy 参数设置为 true,则是 23 个字符串长。

    md5() 函数生成绝对唯一的 ID。

  2. magecreatefromjpeg($uploaded_tmp): 从上传的JPEG文件($uploaded_tmp)创建一个新的图像资源。

  3. imagejpeg($img, $temp_file, 100): 将这个图像资源保存为JPEG格式的临时文件($temp_file),质量设置为100(最高质量)。

  4. imagepng($img, $temp_file, 9): 将这个图像资源保存为PNG格式的临时文件($temp_file),压缩级别设置为9(最高压缩)。

    1. imagedestroy( $img );

    释放图像资源,释放内存。

fu-im2

  1. rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) )

    1. **getcwd()**:返回当前工作目录的路径。
    2. **DIRECTORY_SEPARATOR**:这是一个预定义常量,代表在当前操作系统下使用的目录分隔符。例如,在Windows上是\,在Unix/Linux上是/
    3. **rename($temp_file, $new_location)**:这是一个PHP函数,用于重命名文件或将文件移动到新位置。
  2. **file_exists($temp_file)**:这个函数用于检查文件是否存在。它接受一个文件路径作为参数,如果该文件存在,则返回 true;否则返回 false

  3. unlink($temp_file):这个函数用于删除指定路径的文件。它接受一个文件路径作为参数,删除该文件。

  4. **ini_get('upload_tmp_dir'):这个函数用于获取 PHP 配置中的 upload_tmp_dir 设置值,它指定了上传文件的临时存储目录。三元运算符 (?:)**:用于条件判断。它的格式是 (condition) ? (value_if_true) : (value_if_false)

    • 如果返回空字符串(''),说明 upload_tmp_dir 没有设置。
    • 如果返回非空字符串,说明 upload_tmp_dir 已经设置。
  5. **sys_get_temp_dir()**:这个函数返回系统默认的临时文件目录路径。通常在 Unix/Linux 系统上为 /tmp,在 Windows 系统上为 C:\Windows\Temp

Imagick和GD

在PHP中,有两个主要的库用于处理图像:ImagickGD。以下是它们的简介及对比:

PHP-Imagick

Imagick是PHP的一个扩展,用于图像处理和创建。它是ImageMagick的PHP接口,提供了强大的功能和更高的性能。

优点:

  1. 高级功能:支持复杂的图像操作,如旋转、翻转、裁剪、变换、过滤、绘图等。
  2. 多种格式支持:支持多种图像格式,包括但不限于JPEG、PNG、GIF、TIFF、PDF等。
  3. 高效处理:处理大图像和大量图像时性能较好。
  4. 颜色管理:支持颜色配置文件和颜色空间转换。

示例代码:

1
2
3
4
$image = new Imagick($uploaded_tmp);
$image->stripImage(); // 去除元数据
$image->writeImage($temp_file);
$image->destroy();

PHP-GD

GD库是PHP内置的图像处理库,常用于基本的图像处理操作。它通常用于简单的图像操作,如缩放、裁剪和添加文字。

优点:

  1. 内置库:不需要额外安装,PHP默认自带。
  2. 简单易用:适合基础的图像处理任务。
  3. 广泛支持:大多数共享主机环境都支持GD库。

示例代码:

1
2
3
4
5
6
7
8
if ($uploaded_type == 'image/jpeg') {
$img = imagecreatefromjpeg($uploaded_tmp);
imagejpeg($img, $temp_file, 100);
} else {
$img = imagecreatefrompng($uploaded_tmp);
imagepng($img, $temp_file, 9);
}
imagedestroy($img);

对比总结

  1. 功能:Imagick功能更丰富,适合需要复杂图像处理的应用;GD功能较为基础,但对于简单任务已经足够。
  2. 性能:Imagick在处理大图像或大量图像时表现更好。
  3. 兼容性:GD是PHP的内置库,几乎在所有PHP环境中可用;Imagick需要额外安装和配置。

选择建议

  • 简单图像处理(如缩放、裁剪):GD库足够。
  • 复杂图像处理(如滤镜、旋转、颜色管理):Imagick更合适。

可以根据具体需求选择合适的库进行图像处理。

C:\ENV\phpstudy_pro\WWW\DVWA-master\config\config.inc.php