部分函数在DVWA文件上传high代码详解中解释并演示其用法,在此不再赘述。
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// 检查Anti-CSRF token,即前端传参是带有user_token,session_token',防止CSRF攻击
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// 上传文件信息
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
//$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
// uniqid() 生成一个带前缀、基于当前时间微秒数的唯一ID, md5()计算该字符串(ID+上传文件名)的 MD5 散列值,然后将该散列值与.上传文件名拼接,简单来说,对上传文件进行了重命名(为md5值,导致%00截断无法绕过过滤规则)。
$temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
//它首先检查upload_tmp_dir(上传文件临时目录)是否为空,如果为空,则使用"sys_get_temp_dir()"函数获取系统的临时目录路径;如果不为空,则使用ini_get()函数获取"upload_tmp_dir"参数的值作为临时文件目录路径,这段代码的目的是为了确保能够获取到临时文件的目录路径,以便在需要临时存储文件的情况下使用。
$temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
// Is it an image?
if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
( $uploaded_size < 100000 ) &&
( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
getimagesize( $uploaded_tmp ) ) {
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
if( $uploaded_type == 'image/jpeg' ) {
$img = imagecreatefromjpeg( $uploaded_tmp );
//从指定的JPEG图片文件创建一个新的图像资源
imagejpeg( $img, $temp_file, 100);
} //将一个图像资源保存为JPEG格式的图像文件
else {
$img = imagecreatefrompng( $uploaded_tmp );
//从指定的png图片文件创建一个新的图像资源
imagepng( $img, $temp_file, 9);
} //将一个图像资源保存为png格式的图像文件
imagedestroy( $img );
// 销毁图像
// Can we move the file to the web root from the temp folder?
if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
//使用rename()函数将临时文件移动到指定的目标路径
echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
}
else {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
// Delete any temp files
if( file_exists( $temp_file ) )
//检查临时文件是否存在
unlink( $temp_file );
//删除指定的文件
//使用unlink()函数可以在移动临时文件之后,如果不再需要临时文件,可以将其删除以释放存储空间。
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
//生成toke,这个与 Anti-CSRF token机制有关。在此不在详谈
?>
函数 | 解释 |
---|---|
uniqid() | 生成一个带前缀、基于当前时间微秒数的唯一ID |
md5() | 计算字符串的 MD5 散列值 |
ini_get() | 获取一个配置选项的值 |
imagecreatefromjpeg() | 由文件或 URL 创建一个新图象 |
imagejpeg() | 输出图象到浏览器或文件 |
imagedestroy() | 销毁图像 |
rename() | 重命名一个文件或目录 |
getcwd() | 取得当前工作目录 |
file_exists() | 检查文件或目录是否存在 |
unlink() | 删除文件 |
由于上述函数大多需要与文件上传配合使用,代码较长且不易理解,故不在此演示,仅说明其用法,如需要进行操作,可自行进行演示。
imagecreatefromjpeg()函数从指定的JPEG图片文件创建一个新的图像资源。
它接受一个参数 $uploaded_tmp,这个变量应该是一个包含JPEG图片文件路径的字符串。函数会尝试打开该文件,并将其解析为一个图像资源。
如果成功,imagecreatefromjpeg()函数会返回一个表示JPEG图像的图像资源。如果失败,它会返回 false。
请注意,imagecreatefromjpeg()函数只能用于处理JPEG格式的图像文件。如果需要处理其他格式的图像文件,可以使用相应的函数,如 imagecreatefrompng()•用于PNG格式,imagecreatefromgif()用于GIF格式等。
imagejpeg()函数将指定的图像资源 $img保存为JPEG图像文件。它接受三个参数:图像资源,目标文件路径和图像质量。
第一个参数 $img是要保存的图像资源,通常是通过 imagecreatefromjpeg()或其他创建图像资源的函数获得的。
第二个参数 $temp_file是目标文件的路径和名称,可以是相对路径或绝对路径。
第三个参数 100表示图像的质量,取值范围为0-100,其中100表示最高质量,但文件大小也会相应增加。
注意,imagejpeg()函数只能用于将图像资源保存为JPEG格式的图像文件。如果需要保存为其他格式,可以使用相应的函数,如 imagepng()用于保存为PNG格式,imagegif()用于保存为GIF格式等。
如果保存成功,imagejpeg()函数会返回 true,否则返回 false。
rename()函数接受两个参数,第一个参数是要移动的文件的当前路径和名称,第二个参数是目标路径和名称。
rename()函数会尝试将临时文件移动到目标路径,并返回移动操作是否成功。如果移动成功,它会返回 true,否则返回 false。
请注意,目标路径应该是一个已存在的目录,并且对于移动操作需要有足够的权限。另外,如果目标路径已经存在同名的文件,将会被覆盖。
file_exists()函数接受一个参数,即要检查的文件路径
file_exists()函数会检查指定的文件是否存在。如果文件存在,则返回 true;如果文件不存在或无法访问,则返回 false。
通过使用 file_exists()函数可以在移动临时文件之后,再次确认临时文件是否成功地从原始位置移动到了目标路径。
nlink()函数接受一个参数,即要删除的文件路径。
unlink()函数会尝试删除指定的文件。如果删除成功,它会返回 true;如果删除失败,它会返回false。
通过使用unlink()函数可以在移动临时文件之后,如果不再需要临时文件,可以将其删除以释放存储空间。