File Upload:
- 文件上传漏洞
- 通常是由于对上传文件的类型、内容没有进行严格的过滤、检查,使得攻击者可以通过上传木马获取服务器的webshell权限
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' ] ); //上传目录加上'uploaded'表单参数所提交的文件名
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No 移动文件,将上传的文件移动到/hackable/uploads/
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
-
服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。
-
basename(path,suffix)函数返回路径中的文件名
-
move_uploaded_file() 函数将上传的文件移动到新位置,move_uploaded_file(file,newloc)。
-
文件上传漏洞需满足三个条件
-
(1) 能够成功上传文件 (2) 文件能够被执行 (3) 文件上传的路径必须知道
-
方法:本关满足三个条件,上传一句话木马,使用菜刀直接连接
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?限制文件必须为图片
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>';
}
}
?>
分析,代码中对上传文件的类型和大小做了限制,文件必须为JPEG/PNG文件,大小不能超过100000B
方法一:可以使用burp抓包修改文件的类型,修改为image/jpeg,上传php一句话木马,然后使用菜刀连接
方法二:将木马文件后缀改为png进行上传,使用文件包含的方式尝试用菜刀连接,url为http://127.0.0.1/dvwa/vulnerabilities/fi/?page=hthttp://tp://127.0.0.1/dvwa/hackable/uploads/1.png
- 中国菜刀的原理是向上传文件发送包含apple参数的post请求,通过控制apple参数来执行不同的命令,而这里服务器将木马文件解析成了图片文件,因此向其发送post请求时,服务器只会返回这个“图片”文件,并不会执行相应命令。
方法三:截断绕过规则,
- 上传文件名为1.php%00.png,绕过文件类型检查
High:
源代码:
<?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_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); //取后缀名最后一个.后面的字符串
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Is it an image?后缀名一定要是jpg或jpeg或png,并且大小不超过100k,并且通过文件信息判断图片
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $uploaded_tmp, $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>';
}
}
?>
增加函数:
- strrpos(string,find,start)
函数返回字符串find在另一字符串string中最后一次出现的位置,如果没有找到字符串则返回false,可选参数start规定在何处开始搜索。 - getimagesize(string filename)
函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
可以看到,High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpg”、”.jpeg” 、”*.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。
方法:使用copy语句将图片与php文件合并,使得一句话木马藏在图片文件最后,然后进行上传,使用文件包含形式进行连接菜刀,得到webshell
-
图解
-
copy语句将图片与php文件合并
-
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=hthttp://tp://127.0.0.1/dvwa/hackable/uploads/hack.png