DVWA文件上传impossible之源码详解
2023-6-18 11:56:59 Author: www.freebuf.com(查看原文) 阅读量:4 收藏

1.源码详解

部分函数在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机制有关。在此不在详谈

?>

2.函数

函数解释
uniqid()生成一个带前缀、基于当前时间微秒数的唯一ID
md5()计算字符串的 MD5 散列值
ini_get()获取一个配置选项的值
imagecreatefromjpeg()由文件或 URL 创建一个新图象
imagejpeg()输出图象到浏览器或文件
imagedestroy()销毁图像
rename()重命名一个文件或目录
getcwd()取得当前工作目录
file_exists()检查文件或目录是否存在
unlink()删除文件

3.函数用法

由于上述函数大多需要与文件上传配合使用,代码较长且不易理解,故不在此演示,仅说明其用法,如需要进行操作,可自行进行演示。

imagecreatefromjpeg()

imagecreatefromjpeg()函数从指定的JPEG图片文件创建一个新的图像资源。
​它接受一个参数 $uploaded_tmp,这个变量应该是一个包含JPEG图片文件路径的字符串。函数会尝试打开该文件,并将其解析为一个图像资源。
如果成功,imagecreatefromjpeg()函数会返回一个表示JPEG图像的图像资源。如果失败,它会返回 false。
请注意,imagecreatefromjpeg()函数只能用于处理JPEG格式的图像文件。如果需要处理其他格式的图像文件,可以使用相应的函数,如 imagecreatefrompng()用于PNG格式,imagecreatefromgif()用于GIF格式等。

imagejpeg( $img, $temp_file, 100);

imagejpeg()函数将指定的图像资源 $img保存为JPEG图像文件。它接受三个参数:图像资源,目标文件路径和图像质量。
​第一个参数 $img是要保存的图像资源,通常是通过 imagecreatefromjpeg()或其他创建图像资源的函数获得的。
​第二个参数 $temp_file是目标文件的路径和名称,可以是相对路径或绝对路径。
​第三个参数 100表示图像的质量,取值范围为0-100,其中100表示最高质量,但文件大小也会相应增加。
​注意,imagejpeg()函数只能用于将图像资源保存为JPEG格式的图像文件。如果需要保存为其他格式,可以使用相应的函数,如 imagepng()用于保存为PNG格式,imagegif()用于保存为GIF格式等。
​如果保存成功,imagejpeg()函数会返回 true,否则返回 false。

rename()

rename()函数接受两个参数,第一个参数是要移动的文件的当前路径和名称,第二个参数是目标路径和名称。
rename()函数会尝试将临时文件移动到目标路径,并返回移动操作是否成功。如果移动成功,它会返回 true,否则返回 false。
请注意,目标路径应该是一个已存在的目录,并且对于移动操作需要有足够的权限。另外,如果目标路径已经存在同名的文件,将会被覆盖。

file_exists( $temp_file )

file_exists()函数接受一个参数,即要检查的文件路径
file_exists()函数会检查指定的文件是否存在。如果文件存在,则返回 true;如果文件不存在或无法访问,则返回 false。
​通过使用 file_exists()函数可以在移动临时文件之后,再次确认临时文件是否成功地从原始位置移动到了目标路径。

unlink( $temp_file )

nlink()函数接受一个参数,即要删除的文件路径。
unlink()函数会尝试删除指定的文件。如果删除成功,它会返回 true;如果删除失败,它会返回false。
​通过使用unlink()函数可以在移动临时文件之后,如果不再需要临时文件,可以将其删除以释放存储空间。

文章来源: https://www.freebuf.com/articles/web/369794.html
如有侵权请联系:admin#unsafe.sh