本文将结合靶场对文件上传漏洞的各种类型进行介绍
1.客户端JS验证绕过突破上传
先看代码,仅在前端用js对文件类型进行检测,这种检测方式最容易绕过
function check_file() { var strfileName=form1.file.value; if (strfileName=="") { alert("请选择要上传的文件"); return false; } var strtype=strfileName.substring(strfileName.length-3,strfileName.length); strtype=strtype.toLowerCase(); if (strtype=="jpg"||strtype=="gif"||strtype=="bmp"||strtype=="png") document.getElementById("form1").submit(); else{ alert("这种文件类型不允许上传!\r\n只允许上传这几种文件:jpg、gif、bmp、png\r\n请选择别的文件并重新上传。"); form1.file.focus(); return false; } }
直接上传,被拦截
开burp抓包,改成php
成功上传并执行
2.白名单拦截
白名单拦截即除了白名单上的文件类型,其他的文件类型都不允许上传,碰到白名单,我们只能结合其他漏洞进行利用
3.content-type检测
content-type检测是通过检测content-type来判断文件类型,这种检测方式也很容易绕过
代码如下
$type_array = array("image/pjpeg","image/bmp","image/gif","image/x-png","image/jpeg","image/jpg"); if (!in_array($_fileS['file']['type'] , $type_array)){ echo "上传文件类型不支持"; exit; }
选择一个php文件,然后用burp抓包
把content-type 改成image/jpeg
成功上传
4.文件头检测
通过检测文件头是否为图片的文件头来判断是否为图片
代码如下
function check($image){ $content= file_get_contents($image); if(preg_match("/".chr(0x21).chr(0xff).chr(0x0b).'NETSCAPE2.0'."/",$content)){ return true; }else{ return false; } }
我们可以找一张正常的图片,合成一张图片马来绕过
用文本编辑器打开图片,插入木马
改后缀为php上传
成功执行
5.iis6.0解析漏洞
条件: iis6.0 文件名可控
原理:
*.asp;.jpg 像这种畸形文件名在“;”后面的直接被忽略,也就是说当成 *.asp文件执行。
选择文件,burp抓包
改文件名
成功执行
6.iis6.0目录解析漏洞
文件夹为xx.asp,只要上传文件到这里,都会把文件当成asp执行
条件 iis6.0 只支持asp,cer
先看代码
我们创建目录,传文件
抓包
文件上传成功
蚁剑链接
7.%00截断
应用场景: 直接截断文件名(php版本小于5.3.29 且 magic_quotes_gpc = Off) 创建目录可控%00截断创建目录 利用iis6.0解析漏洞 截断参数
%00截断创建目录
编码一下
可以看到,实际创建的文件夹是截断后的文件夹
文件截断上传
编码一下
成功上传执行
8.htaccess文件
这种方法通常用在黑名单,可以上传.htaccess文件的情况
.htaccess文件攻击即结合黑名单攻击服务器的 .hatccess文件。 通过move_uploaded_file函数把自己写的 .htaccess文件覆盖掉服务器上的这样就可以解析定义名单了。 .htaccess文件用处:通过 .htaccess文件调用php解析器取解析一个文件名中包含 “XXX” 字符串(自定义字符串)的任意文件,无论你的文件名是什么样子,只要包含定义的字符串(“XXX”),的都可以被以php的方式解析。 .htaccess文件内容: SetHandler application/x-httpd-php .htaccess攻击成功前提 .htaccess文件作为局部变量作用文件成功作用的两个条件: 1.Allow Override All 2.LoadModule rewrite_module modules/mod_rewrite.so #rewrite模块为开启状态
我们先上传图片
然后编写.htaccess文件上传
访问木马,成功执行
9.利用系统特性突破上传
上传文件名a.php:.jpg的时候 会在目录下生成a.php的空白文件 php+windows+iis 利用PHP和Windows环境的叠加特性,以下符号在正则匹配时的相等性: 双引号" = 点号. 大于符号 > = 问号? 小于符号 <= 星号* 文件名.<或文件名.<<< 或文件名.>>>或文件名.>><空文件名 写入filename.<<<
首先,我们选择一张图片,用burp抓包,创建一个名为eval1.php的空白文件
然后,我们写入木马到刚刚创建的空白文件
eval1.<<< eval1.>>> #两种都可以
成功执行
例如upload-labs的第10关也是利用了windows的系统特性,忽略后缀后的点来绕过的
源码如下
$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(".php",".php5",".php4",".php3",".php2",".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"); $file_name = trim($_fileS['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file = $_fileS['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '此文件类型不允许上传!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} //第一个,获取文件名,第二个删除点,所以第二个点没了,第三个,获取后缀,这时候获取到的是.php.空格,第四个,转换小写,第五个,去掉::$DATA,第六个,首尾去空格,最后变成 .php.,最后一个点并没有去掉,只不过Windows后缀名最后不让出现点,所以传上去以后Windows默认给你去掉了
所以用burp抓包,改后缀为.php. .
成功执行
10.利用NTFS交换数据流绕过上传
windows+php环境,那我们在上传文件名里面,文件名加上::$data
,这个时候,就会把::$data
之后的数据当做文件流,进行处理,而且,它不会检测后缀名,而且会保留::$data
之前的文件名,其实它的目的就是为了注入检查后缀名,所以我们就利用这个特性进行绕过
:$DATA 创建文件 ::$DATA 创建和写入文件
选择文件上传,用burp抓包
在文件后面添加 ::$DATA
访问木马,成功执行
11.空格绕过上传
选择文件,burp抓包,在文件名后面加一个空格
成功上传执行
12.双文件上传
我们直接审查元素修改前端源码,将一个文件改成两个
第一个选择正常的图片文件,第二个我们选择木马文件
成功上传执行
13. .user.ini绕过
这里结合upload-labers的第五关
源码如下,并未禁止.user.ini上传
$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(".php",".php5",".php4",".php3",".php2",".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"); $file_name = trim($_fileS['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file = $_fileS['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '此文件类型不允许上传!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }}
先上传一个以auto_propend_file=eval.jpg为内容的.user.ini文件(用户自定义的配置文件) .user.ini文件里的意思是:所有的php文件都自动包含1.gif文件,.user.ini相当于一个用户自定义的php.ini。 然后再上传一个内容为一句话木马的命名为eval.jpg
先上传.user.ini
再上传图片马
成功执行
14.双写绕过
以upload-labs的11关为例
$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini"); $file_name = trim($_fileS['upload_file']['name']); $file_name = str_ireplace($deny_ext,"", $file_name);//这里替换为空,且只替换1次,所以我们可以用.phpphp或.pphphp绕过 $temp_file = $_fileS['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }}
成功绕过上传
#如无特别声明,该文章均为 原创,转载请遵循
署名-非商业性使用 4.0 国际(CC BY-NC 4.0) 协议,即转载请注明文章来源。
#最后编辑时间为: 2022-08-03 15:12:14