什么是文件上传漏洞:
大部分的网站和应用都有上传功能,如用户头像上传,图片,logo,文档等。一些文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者像某个可通过web访问的目录上传任意php文件,并能够将这些文件传递给php解释器,就可以在远程服务器上执行任意php脚本。
当系统存在文件上传漏洞同时攻击者可以将病毒,木马,webshell,其他恶意脚本或者是包含了脚本的图片上传到服务器,这些文件将对攻击者后续攻击提供便利。根据具体漏洞的差异,此处上传的脚本可以使正常后缀的php,asp以及jsp脚本,也可以是篡改后缀后的这几类脚本。
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
造成文件上传漏洞的原因及原理:
原因:
1 对于上传文件的后缀名(扩展名)没有做较为严格的限制
2 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
3 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
4 对于web server对于上传文件或者指定目录的行为没有做限制
原理:
在 WEB 中进行文件上传的原理是通过将表单设为 multipart/form-data,同时加入文件域,而后通过 HTTP 协议将文件内容发送到服务器,服务器端读取这个分段 (multipart) 的数据信息,并将其中的文件内容提取出来并保存的。通常,在进行文件保存的时候,服务器端会读取文件的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个文件名 ( 为了防止重复 ),并且加上原始文件的扩展名来保存到服务器上。
文件上传可能带来的安全问题:
-上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行;
-上传文件是flash的策略文件crossdomiain.xml,黑客用以控制flash在该域下的行为;
-上传文件是病毒、木马,黑客用以诱骗用户或者管理员下载执行;
-上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。
low
打开,修改级别,打开文件上传,开始闯关。
随便上传一个文件,我们发现图片jpg格式是可以的,继续,png格式呢。
我们发现图片png格式是可以的,继续,php格式呢
不得了,竟然可以成功上传PHP格式,在这里不言而喻文件上传漏洞就是这么简单被大家发现了。我们可以通过构造一句话木马直接上传文件,来查到很多东西。
如上图,我们简单的构造了一句话木马,把文件上传,上传成功之后。
访问一下该php,发现什么也没有,证明木马上传成功:
验证方式一:
输入:?777=phpinfo();
会显示出php的信息
验证方法二:
小马一般配合其他工具一起使用,这里我们使用中国蚁剑进行连接:
因为在我的kali中提前装好了蚁剑,所以这里直接输入快捷命令antsword
就打开了:
右击点击添加数据,填入我们上传的php文件的url地址,连接密码为777
:
点击测试连接:
连接成功后,我们就可以点击添加,右击添加好的数据,打开虚拟终端,我们就可以做一些操作,如:添加用户,查看当前用户:
Medium
然后进入下一关
上传php木马,我们发现这一关对文件格式进行了限制。
方式一:
我们可以通过上传php文件,然后通过抓包,修改类型为它要求的类型,发现能过上传成功。
上传成功:
验证:
蚁剑连接
方法二:
那么我们就把我们的文档后缀修改一下,上传成功了,可是要执行里面的代码就需要触发PHP代码解释器,这时候我们需要考虑如何再上传之后再把后缀名改回来。
上传成功:
验证:
high
查看源码:
源码中对上传文件的类型做了限制,并且会检查上传图片文件的内容
● 使用getimagesize() 进行文件内容检测,只检测文件头部。
方式一:
上传成功:
验证:
验证一:
验证二(连接蚁剑):
完全防御
<?php
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 "<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 );
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
任意文件上传防御
代码角度
-
采用白名单策略,严格限制上传文件的后缀名;
-
上传文件重命名,尽量少的从客户端获取信息,包括文件名、文件类型、文件内容等;
-
文件内容检测;
-
进行二次渲染,过滤掉图片马中的恶意代码;
-
避免文件包含漏洞;
-
严格处理文件路径,防御00 截断漏洞;
-
检测Token 值,防止数据包重放。
业务角度
-
强口令策略,避免恶意攻击者登录网站后台;
-
尽量避免Web 用户修改上传白名单。
容器角度
- 及时更新Web 容器,防止解析漏洞产生。
- 禁用Web 容器PUT 方法。
系统角度
避开空格
、点 .
、 ::$DATA
等系统特性。
服务器部署
-
严格控制权限。
-
建立单独的文件存储服务器,类似于站库分离。