pass1
前端验证,使用bp抓包改后缀
pass2
验证MIME类型,使用bp抓包,更改Content-Type 即可
pass3
黑名单限制,可以上传 .php3 .php5 .pthml 等等后缀, 但是要在phpstydy配置文件中更改,(我使用2018版才行)
pass4
由于我们使用的时 apache 中间件,于是我们可以上传 .htaccess 文件
将 上传的图片马解析为 php脚本执行
pass5
这里的思路是没有进行循环验证,只验证一次
我们可以上传 muma.php. . 文件, trim()去除字符串两端空格,然后deldot()删除文件名末尾的小数点,但是遇到空格就停止了,文件名变为 muma.php. (空格) ,最后使用trim() 去掉末尾的空格, 后缀变为: .php.
由于windows会在文件命名的时候自动去除文件名后的小数点和空格,于是上传之后的文件名为: muma.php
pass6
对比之前的条件发现,少了大写转小写的函数,于是可以大小写绕过
pass7
少了trim()函数,直接在 .php 后加空格绕过,windows生成文件时会自动将文件名后缀后面的空格去除。
pass8
少了去除文件尾的小数点的函数,在 .php 后加小数点 .php. 绕过
pass9
少了去除字符串 ::$DATA 的函数
把 ::$DATA 将在 .php 后面即可
php在window的时候如果文件名+"::$DATA“会把::$DATA 之 后 的 数 据 当 成 文 件 流 处 理 , 不 会
检 测 后 缀 名 . 且 保 持 ” : : $DATA之后的数据当成文件流处理,不会检测后缀名.且保持”:: $DATA之后的
数据当成文件流处理,不会检测后缀名.且保持”::$DATA"之前的文件名
pass10
和pass5一样
pass11
发现会把黑名单中的后缀名替换为空,但是只进行一次,于是可以进行双写绕过
muma.pphphp => muma.php
pass12
第十二关我们看代码,可以得知是一个白名单,只允许上传'jpg','png','gif'格式的文件。但是上传路径是可以
控制的,可以使用%00进行截断。
%00只能用于php版本低于5.3的。这里我们需要把phpstudy切换一下版本,
把magic_quotes_gpc关闭
00截断的原理
00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即
0x00)作为字符串的结尾。操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符
号。因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的。00截断通常用来绕过web软waf
的白名单限制。
于是,我们可以在save_path 后面加上 a.php%00 截断后面的png图片名,造成上传文件变为php文件
访问 /upload/x.php:
pass13
这一题还是 %00 截断,但是这一题是post请求方式,所以需要将 %00进行urldecode 解码
pass14
这一题考察文件头内容判断,在文件内容第一行加上相应文件的头标识即可,然后配合文件包含漏洞,将对应图片中的php代码引入即可执行出相应脚本
GIF:
JPG
使用DOS命令行制作图片马,或者直接在文件后面加上也是一样的效果
copy 1.jpg/b + shell.php/a muma.jpg
PNG
和jpg类似,与图片合成,制作图片马
注意php版本问题,如果低版本php,使用文件包含漏洞访问图片马,可能会报错。
pass15
和pass14类似
我们来看这个 getimagesize函数,这个函数的意思是:会对目标文件的16进制去进行一个读取,去读取头几个字
符串是不是符合图片的要求的
pass16
与pass14类似,要把php_exif 模块打开
exif_imagetype() 读取一个图像的第一个字节并检查其签名。
本函数可用来避免调用其它 exif 函数用到了不支持的文件类型上或和 $_SERVER['HTTP_ACCEPT'] 结合使用来检查浏览器是否可以显示某个指定的图像。
pass17
二次渲染
imagecreatefromjpeg()函数
二次渲染是由Gif文件或 URL 创建一个新图象。成功则返回一图像标识符/图像资源,失败则返回false,导致图片马的数据丢失,上传图片马失败。
进行通关
按照原来的方法进行上传,我们可以发现还是可以上传的,但是配合包含漏洞却无法解析,这时我们把上传的图片复制下来用Notepad打开,发现我们原来写的php代码没有了,这就是二次渲染把我们里面的php代码删掉了。
我们把原图和他修改过的图片进行比较,看看哪个部分没有被修改。将php代码放到没有被更改的部分,配合包含漏洞,就可以了。(GIF通关法)
png、jpg可以使用大佬写的脚本生成图片马
pass18
条件竞争
从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。
这么看来如果我们还是上传一个图片马的话,网站依旧存在文件包含漏洞我们还是可以进行利用。但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。
那还怎么搞?上传上去就被删除了,我还怎么去访问啊。
不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了(这时由于文件正在访问,所以也就删除不了了)。这个也就叫做条件竞争上传绕过。
我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。
为了更好的演示效果,把一句话木马换一下改为:
<?php fputs(fopen('mm.php','w'),'<?php @eval($_POST["cmd"])?>');?>
把这个php文件通过burp一直不停的重放,然后再写python脚本去不停的访问我们上传的这个文件,总会有那么一瞬间是还没来得及删除就可以被访问到的,一旦访问到该文件就会在当前目录下生成一个mm.php的一句话。在正常的渗透测试中这也是个好办法。因为单纯的去访问带有phpinfo()的文件并没有什么效果。一旦删除了还是无法利用。但是这个办法生成的mm.php服务器是不会删除的,我们就可以通过蚁剑去链接了。
pass19
条件竞争
pass20
解法一: 使用 %00截断
解法二:
move_uploaded_file()有这么一个特性,会忽略掉文件末尾的 /.
pass21
这一关是利用数组绕过验证
这一题先上传一个php文件,
修改Content-Type 绕过MIME 验证
然后会判断save_name是否为空,不为空,文件名就获得save_name 值
我们在图片中可以看到,save_name 我们设置成了一个数组,于是 $file 就是一个数组,绕过了explode()函数
然后使用end()函数, $ext 获得数组最后一个元素,即 jpg,绕过了后缀判断in_array()
然后, f i l e n a m e 就为: a a a . p h p / . 由于 c o u n t ( file_name 就为: aaa.php/. 由于count( filename就为:aaa.php/.由于count(file) 等于数组的长度,因为数组只要两个元素,所以长度为2,于是 f i l e [ c o u n t ( file[count( file[count(file) - 1] = f i l e [ 1 ] 。因为 file[1] 。因为 file[1]。因为file[1] 没有设置值,于是该值便为空,
则 $file_name = aaa.php/. 我们知道move_uploaded_file()有这么一个特性,会忽略掉文件末尾的 /.
所以上传文件名就变成了 aaa.php 妙啊
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数
_file()有这么一个特性,会忽略掉文件末尾的 /.**
所以上传文件名就变成了 aaa.php 妙啊
[外链图片转存中…(img-1o1qAKcq-1671939579820)]
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数
https://blog.csdn.net/weixin_47598409/article/details/115050869