文件上传是Web应用的必备功能之一!
如果服务器配置不当或者没有进行足够的过滤,Web 户就可以上传任意件,包括恶意脚本件,exe 程序等等,这就造成了件上传漏洞。
漏洞的成因
服务器配置不当
Web 应开放了文件上传功能,没有对上传的件做够的限制和过滤。
在程序开发部署时,没有考虑到系统的特性或组件的漏洞,从导致限制被绕过。
漏洞危害
上传漏洞最直接的威胁就是上传任意件,包括恶意脚本、程序等。
直接上传后门文件,导致网站沦陷。
通过恶意件,利其他漏洞拿到管理员权限(提权),导致服务器沦陷。
通过文件上传漏洞获取的网站后门,叫WebShell。
WebShell是一个网站的后门,是一个命令解释器。通过Web方式(HTTP协议)传递命令消息到服务器,并且继承了Web用户的权限,在服务器端执行命令。
WebShell从本质上讲,就是服务器端可运行的脚本文件,后缀名通常为:
.php.asp.aspx.jsp...
WebShell通常接收来自于Web用户的命令,然后在服务器端执行!
网站木马、木马后门、网马
小马:或一句话木马,与中国菜刀配合。
特点:短小精悍,功能强大!
三大基本功能:文件管理、虚拟终端、数据库管理
中国菜刀、蚁剑、冰蝎,CKnife ......
一句话木马:
10版本:
16版本:
蚁剑:
大马:与小马相比,代码量比较大。
Windows Server 2008
GetShell
GetShell是获取WebShell的过程或结果!
文件上传漏洞的利用是GetShell的主要方式,但不是唯一手段。
文件上传漏洞的攻防
黑名单策略,类似一个列表,在列表中写一些规则和条件。
黑名单就是非法条件,白名单就是合法条件。
黑名单:
$deny_ext =array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
代码审计:
对文件上传做过滤
限制文件类型
查看源代码,发现只对文件类型进行检测:
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 ) ) { 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.';}} 上传的件没有重命名Content-Type 类型名单判断Content-Type 类型客户端可控(客户端户可以修改此类型)可以利Burp Suite 抓包、改包
件后缀名和件内容检测
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.'; }}
代码审计:
检测Token 值,防数据包重放件重命名件后缀名名单检测Content-Type 类型名单检测件内容头部检测次渲染,成新件删除缓存件
图片木马:
图没有办法直接利,需要配合其他漏洞。但是需要知道的是,图中包含了恶意代码!
copy imgName/b+yjh/a newImgName
制作图片木马:
合并:正常图片+一句话木马
上传成功,需要利用此漏洞,需要结合其他漏洞,比如,文件包含!
其他方法:
windows 7或windows 2008下
完全防御
源代码
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 phpImagick 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} succesfullyuploaded!"; } 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 orPNG images.'; }}// Generate Anti-CSRF tokengenerateSessionToken();?>
代码审计:
检测Token 值,防数据包重放件重命名件后缀名名单检测Content-Type 类型名单检测件内容头部检测次渲染,成新件删除缓存件
Content-Type:用于定义网络文件的类型和网页的编码,告诉文件接收方将以什么形式、什么编码读取这个文件!
件上传漏洞利用的条件
前提条件
Web 服务器开启件上传功能,Web 户可以使该功能。Web 户(www-data|apache)对标录具有可写权限,甚具有执权限。般情况下,Web 录都有执权限。"完美利" 意味着件可以执,也就是说代码可以被服务器解析。服务器开启了PUT 法。
GetShell 的些影响因素
以 upload-labs 来探讨相关问题
Pass-01:
其他可执的件后缀名
php
php|php5|php4|php3|php2|php1
html
html|htm|phtml|pht
asp
asp|aspx|asa|asax|ascx|ashx|asmx|.cer
jsp
jsp|jspa|jspx|jsw|jsv|jspf|.jtml
.htaccess 攻击
.htaccess 是 Apache 服务器分布式配置件,通过它可以实现Web服务器中的文件的解析方式、重定向等配置!
如果某个录下存在该件, .htaccess 件中的配置会覆盖掉 Apache 全局配置件!(可以实现将扩展名.jpg/.png等文件当作PHP文件解析!)
httpd.conf 的配置,作域是当前录及其录有效。
此处想象空间常。
开启.htaccess的配置
Options FollowSymLinks AllowOverride None 改为Options FollowSymLinks AllowOverride All
mod_rewrite.so的注释去掉,开启rewrite模块!
LoadModule rewrite_module modules/mod_rewrite.so
.htaccess文件上传配置
两种方法将其他扩展名的文件当作代码来解析:
指定文件名
指定文件后缀
将 .jpg 件当作 PHP 件解析
AddType application/x-httpd-php .jpg
匹配固定的件名
SetHandler application/x-httpd-php
件名中包含php 关键字
4.php.png
AddHandler php5-script php
系统特性
忽略写
1. 脚本程序对写敏感,PHP 和php 是完全不同的两个件后缀名。2. Windows 系统对写不敏感。
忽略件名末尾的点
# windows[info.php.] -> [info.php]
忽略件名末尾的空格
# windows[info.php ] -> [info.php]
数据流 ::$DATA
# windows# 数据流会被系统忽略[info.php::$DATA] -> [info.php] 文件截断上传
PHP特性:00截断
当PHP的版本低于5.3.4时,会把%00当作结束符,导致后面的数据直接忽略!
(当函数读到 0x00(%00) 时,会认为文件已经结束!)
理解:
比如上传:tony.php%00.jpg
.jpg是合法后缀名
服务器端在保存.jpg时,函数会认为%00是终止符,于是保存的是tony.php!
注意:可以将%00进行URL编码
竞争条件文件上传
多个线程在没有进行锁操作或者同步操作的情况下同时访问同一个共享代码、变量、文件等,运行的结果依赖于不同线程访问数据的顺序!
理解:
不作同步或锁操作:
一个线程允许上传任意文件,另一个线程检查文件是否包含WebShell等!
存在文件已经上传,但检查不是太及时!中间存在时间差,这个时候,就可以被利用!
总结
绕过
前端JS检测绕过
// 删除检测代码(浏览器插件可以实现)// 修改为允许上传的文件后缀名,BP抓包,修改为可执行的文件,再放行!
2 .文件后缀绕过
// 修改服务器的配置文件,允许能够解析可执行的文件!// Apache的解析顺序,从右到左,直到能够识别!// test.php.xxxx,如果xxxx不能识别,但识别了.php,就当php文件解析!
文件类型绕过
Content-Type // 修改为允许的上传类型(通过客户端传输,可以修改!)
PHP%00截断
PHP版本小于5.34,PHP的magic_quotes_gpc为Off状态!
竞争条件绕过
利用BP中的Intruder功能不断发送上传文件的请求,消耗服务器端的资源,让检查线程不能及时检查上传是否合法!
防御
白名单限制上传的类型(客户端检测)
服务器端文件检测
对上传的文件进行随机重命名,指定文件的扩展名!
对上传的文件,就行权限管理,可以去掉文件可执行权限!
......