原理
危害
产生条件
本文将结合靶场对文件上传漏洞的各种类型进行介绍
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 . '文件夹不存在,请手工创建!';
}}
成功绕过上传

评论 (0)