目录
6.点号绕过 可以看到黑名单里没有下面的这个函数对"."处理,利用Windows特性,会自动去掉后缀名中最后的“.",可在后缀名中加“."绕过;
一、客户端
1.使用burp将所有JS删除,再上传phpinfo.php或者F12删除JS,在上传php文件
2.绕过js验证,使用burp拦截,并将后缀名从jpg改为php
二、服务端
1.MIME-Type验证
(多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名问及那被访问的时候,浏览器会自动使用只当应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
方法:将Content-Type:改为符合条件类型的后缀名的Type(例如imag/jpeg)
2黑名单认证
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".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");
$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)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
1.后缀名
1)基于白名单验证,基于黑名单验证
2)这一关禁止.jsp .php .asp .aspx后缀名的文件上传
但是我们可以用其他的后缀名,例如php1、php2、phtml、php5
(注意:上传成功后,文件名会被更改,所以需要查看文件上传的位置及文件名)
2..htaccess
(htaccess文件是Apache服务器的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、进制目录列表、配置默认文档等功能。)
(httaccess文件内容:SetHandler application/x-httpd-php 设置当前目录所有文件都是用PHP解析,那么无论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当作PHP执行。不符合则报错)
1)创建1.htaccess,并将其上传:
<FilesMatch "上传的图片马的文件名"
SetHandler application/x-httpd-php
</FilesMatch>
2)再上传图片马即可
3..user.ini
与前两关相似,再过滤了.htaccess
但是还有个ini配置文件可以利用。先上传一个以auto_prepend_file=1.gif为内容的.user.ini文件,然后再上传一个内容为php的一句话脚本,命名为1.gif;
.user.ini文件里的意思是:所有php文件都自动包含1.gif文件。.user.ini相当于一个用户自定义的php.ini。
4.大小写绕过
如果再源码中发现这种对后缀名没有统一的大写或者小写处理
$file_ext = strtolower($file_ext); //转换为小写
可以通过大小写绕过(例如info.phP)
5.空格绕过
发现处理函数中没有对文件后缀名去空处理,可在后缀名中加空绕过
$file_ext = trim($file_ext); //收尾去空
Windows系统下,对于文件名中空格会被作为空处理,程序中的检测代码却不能自动删除空格。从而绕过黑名单。(需要使用BURPSIUITE阶段HTTP请求之后,修改对应的文件名添加空格)
6.点号绕过
可以看到黑名单里没有下面的这个函数对"."处理,利用Windows特性,会自动去掉后缀名中最后的“.",可在后缀名中加“."绕过;
$file_name = deldot($file_name);//删除文件名末尾的点
7.::$DARA绕过
没有下面的函数对后缀名进行“::$DATA"处理,利用windows特性,如果上传的文件名test.php::$DATA会在服务器上生成一个test.php的文件,其中内容和上传内容相同,并被解析,可在后缀名中加”::$DATA"绕过
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
8.点号绕过拼接并绕过前面的两次过滤
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
可以看出这一关是将文件名进行过滤操作后,将文件名拼接在路径后面,所以需要绕过前面的首位去空以及去点。即构造phpinfo. .
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
$is_upload = true;
}
9.双写绕过
$file_name = str_ireplace($deny_ext,"", $file_name);
这里用str_ireplace函数将符合黑名单中的后缀名进行替换为空,所以可以双写绕过
二、白名单认证
1.GET型%00截断,
由于$img_path直接拼接,因此可以利用%00截断绕过
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
2.post型0x00
(0x00截断使用在POST中,且是在二进制中进行修改,因为POST不会像GET那样对%00进行自动解码)
1)0x00截断上传及原理(0x00是十六进制表示方法,是ASCII码为0的字符,在有些函数处理时,会把这个字符当作结束符)
<%
path="upfiles/picture/"
file="20121212.jpg"
upfilename=path&file'最后的上传地址'
%>
upfilename即为最终名字,意思为如果地址为picyure/1.php+,文件名为1.jpg+则最终上传上去的文件路径为picture/1.php+1.jpg,0x00截断的思路即读取到0x00时,认为已经结束,不会再读取后面将要拼接的1.jpg,认为是php文件,此处利用到的就是0x00的截断漏洞
方法:首先bp上传图片,将数据包发到repeater,并对/uploads/后面加上1.php+,此处相当于上例中的path;然后打开hex(16进制),找到+对应的代码,0x00的意思为16进制00,所以将+对应的进制改为00;
00截断原理分析(0x00,%00,/00)(这是看的别的大佬对其的解释)
%00截断:在url中%00表示ascii码中的0,而ASCII中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就认为读取结束,例如https://mp.csdn.net/upfiles/?filename=test.php%00.txt 此时输出的是test.php就绕过了后缀限制,可以上传webshell
0X00截断:0x开头表示16进制,0在十六进制中是00,0x00就是%00解码成的16进制
/uploads/1.php a
这里在php的后面加了一个空格和字母a,其实a写不写都可以,这里加a是为了显示空格的位置。空格是为了占位,方便修改00.
然后打开hex,(空格的16进制为0x20)修改为16进制内容,把20改为00;就绕过了后缀限制,可以上传webshall了
2)如何利用00截断(参考于https://blog.csdn.net/weixin_44840696/article/details/90581104)
https://blog.csdn.net/weixin_44840696/article/details/89505803文件上传漏洞靶场源码关键语句分析
- 对后缀名的00绕过只能绕过前端验证,因为如果是后端验证,那么即使后缀被截断了,处理之后为.php,还是会被后端验证拦截。
- 文件上传的条件:1.后缀检测,合格则进行上传路径拼接 2.拼接路径和文件名,组成文件上传路径,组成文件上传路径
- 这里决定文件上传后被保存在文件夹中的真实后缀名是文件上传路径,因为上面一大堆代码只不过是对后缀名进行各种处理和验证,这里相当于一个过安检的过程,最后决定文件到底是什么名字,什么后缀名,要看“文件上传路径”;
-
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='上传出错!';
这个源码中的文件路径是上传路径和文件名拼接的,也就是说也许上面的后缀被处理了半天能通过安检了,但是最后上传后的文件后缀却不一定是这个被处理半天的“后缀”,这里拼接的是$file_name这个变量,它和后缀名变量$file_ext是不同的,$file_name没有经过这个变量,它和后缀名变量$file_ext是不同的,$file_name没有经历那一堆安检处理,只是从它身上截取了一个$file_ext变量拿去安检
-
两个方法1)路径拼接向上图的代码一样,直接使用的$file_name这个文件名,这时文件名还是可以包含截断字符的,路径拼好后可以被截断成想要的.php (根据windows特性)2)文件路径可控,若抓到的包中在path:uploads/,就可以直接把路径构造uploads/xxx.php%00,先构造一个存在截断字符的后缀“等着“真正的文件名,或后缀名,因为不管他是啥,都会被截断丢弃,因为这里已经到了最后阶段,不会再有安检过程了
三、图片马
1.文件包含利用
制作图片马:copy 1.jpg/a+1.txt/b 2.jpg