Pass-01-前端js绕过

随机上传一个PHP后缀文件

发现弹出弹窗提示,不允许上传非图片类型文件,看下前端代码

发现前端js对上传文件类型做了判断,于是抓包,先上传一个jpg结尾的文件,然后在抓包修改文件后缀为php,放包,成功

Pass-02-文件类型绕过

同样先上传一个PHP的后缀文件,发现提示文件类型不正确

于是查看源代码,发现对文件类型做了限制

那么抓包修改文件类型就是了

Pass-03-黑名单绕过-后缀名

黑名单过滤,禁止上传.asp|.aspx|.php|.jsp后缀文件。

思路:主要考察可执行后缀,在Apache中phtml、php3等没有

可执行后缀可以在httpd.conf中查找AddType application/x-httpd-php,看apache配置中是否有设置,如果没有配置,可自行配置构造环境)

例如:AddType application/x-httpd-php .php .php3 .phtml

由于我使用的是最新的phpstudy+Windows,就不复现了,大致思路是这样就OK了

Pass-04-黑名单绕过-.htaccess

还是一样上传一个PHP的后缀文件夹,发现就提示此文件不允许上传

看了下源代码过滤,发现基本都过滤了,但没有过滤.htaccess,于是可以利用.htaccess特性去进行绕过。

htaccess文件时Apache服务器中的一个配置文件,负责相关目录下网页配置,可以帮我们实现网页301重定向,自定义404错误页面,改变文件扩展名等功能,其中.htaccess文件内容:SetHandler application/x-httpd-php设置当前目录所有文件都使用PHP解析,无论上传任何文件,只要符合php语言代码规范,就会被当做php文件执行。

但要实现这一绕过,得保证apache配置文件(httpd.conf)中设置AllowOverride为All

步骤:

1.上传.htaccess文件

1
SetHandler application/x-httpd-php

2.上传一句话木马,后缀名改为.jpg

1
<?php phpinfo(); ?>

3.访问

Pass-05-黑名单绕过-.user,ini

还是同样上传一个php的后缀文件,发现提示文件类型不允许上传,查看源码,发现连.htaccess也过滤了,但是没有过滤.user.ini

于是上传一个以auto_prepend_file=a.gif为内容的.user.ini文件,然后再上传php脚本,文件命名为a.gif,与前面内容为·····=a.gif相对应,.user.ini文件内容意思为:所有的php文件都自动包含a.jif文件。.user.ini将所有php文件自动包含任意木马文件执行,就类似于上面的.htaccess绕过大致原理思路是是一样的

1
2
3
4
5
###.user.ini
auto_prepend_file=a.jpg

###a.jpg
<?php phpinfo(); ?>

上传后,重启服务,然后访问readme.php时会自动包含a.jpg

但是我发现还是没能成功,百度解决了好久还是没有一个正确的解答,基本都是这样的方式,可能跟个种版本的问题有关系,后面也就没有去弄了

但是我发现这一关可以用”. .”(中间有一个空格)去绕过,但脱离了本身出题的思路了,因为源码的过滤只过滤了一次,反正有很多关都可以用这个思路去绕过,算是一个小的bug吧

Pass-06-黑名单绕过-大小写

普通上传一个php后缀文件,然后抓包修改后缀为.PHP,由于在windows中不区分大小写,所以同样能以.php文件执行

放包,成功上传,访问存储位置,成功执行

Pass-07-黑名单绕过-空格绕过

同样抓包上传一个.php文件,然后在后缀名后面加上一个空格即可绕过,因为在windows下时,会自动省略空格,从而达到执行目的,在上传时由于没有做好过滤从而导致在文件后缀加空格,而这个空格被当做了字符进行判定,从而没能过滤.php

放包,成功上传

访问返回地址,成功

Pass-08-黑名单绕过-点号绕过

在.php后面加上一个点(.php.)上传,在上传时,.会被当做字符处理去进行过滤判断,然而在Windows下,文件后缀名的最后一个点会被自动去除,从而执行木马

Pass-09-黑名单绕过- 特殊字符(::$DATA)绕过

在windows情况下,文件名加“::$DATA”,会把::$DATA之后的数据当成文件流处理,不会被检测后缀名,保持之前的文件名,简单点来说,就是在Windows系统下,如果上传的文件名中a.php::$DATA会在服务器上生成一个test.php的文件,其内容与所上传文件内容相同,并被解析,所以注意的是,在访问时,应以a.php去进行访问

从上传文件存储处可以看见我们所上传的是phpinfo.php::$DATA文件,在上传成功之后,除了对名字从定义之外,::$DATA被去掉了。

Pass-10-黑名单绕过-.php.(空格).

虽然在源代码中已经自动删除了文件后面的.,但尝试了加两个点,发现成功绕过,应该只是删除了一个点,绕后利用Windows特性,默认执行为php文件

上传phpinfo.php. .形式的样式

Pass-11-黑名单绕过-双写绕过

检查源代码,发现str_ireplace函数将符合黑名单中的后缀名进行替换为空,于是想着加多加一个能行不,发现成功绕过,其实感觉跟上一题一样都是只进行了一个过滤或替换,包括上一题的思路可以用到1-10关符合的,都可以利用只进行一次过滤判断,去绕过,应该算是一个小的BUG吧,毕竟跟提示的绕过方式不一样

上传文件形式(构建后缀让其从左到右识别php后,进行替换,但还剩下前后形成的php)

phpinfo.pphphp

Pass-12-白名单绕过-get型0x00截断

查看源码,发现只允许上传jpg、png、gif文件,抓包发现保存路径可控,于是想到可利用00截断绕过

其主要原理为:在系统读取文件名,如果读取到0x00,就会读取结束,0x表示16进制,URL中%00解码成16进制就是0x00

注意:需要php版本<5.3.4,并且magic_quotes_gpc关闭

eg:www.xxx.com/aa.php%00.jpg ——》 www.xxx.com/aa.php

抓包构造绕过

访问时,要去掉php后缀后的内容,只留下aa.php

Pass-13-白名单绕过-post型0x00截断

post类型的00截断与get类型的00截断在于%00截断在get中被url解码之后是空字符,但是在post中%00不会被url解码,所以需要在hex中修改16进制00截断

在hex中找到phpinfo.php,p后的0d(根据情况自行判定)改为00后放包上传

复制图片地址去掉.php后面的部分,访问

Pass-14-图片马,文件包含利用

由源码可知,该关卡设置的验证方式为文件头检查,如果有不清楚具体的判断,可通过在index.php中找到对应的位置加入echo var_dump($strInfo);去查看返回的值去辅助理解,所以这个地方可直接利用图片马的样式进行上传绕过。

制作图片马copy 1.jpg/b+2.php/a 3.jpg,然后上传,上传成功后,利用文件包含解析图片马里的php脚本,file为我们的图片马位置

Pass-15-图片马,文件包含利用

查看发现getimagesize()函数,而该函数的作用就是获取图像信息,$info2指的文件的类型image_type_to_extension-根据指定的图像类型返回对应的后缀名,绕过方式也就是利用图片欺骗,用上一关的图片马即可绕过。

上传访问

Pass-16-图片马,文件包含利用

exif_imagetype($filename)—读取一个图像的第一个字节并检查其签名

这一关需要开启php_exif模块

Pass-17-图片马加二次渲染

这里用gif,容易绕过二次渲染,关于二次渲染是根据上传的图片生成一个新的图片,然后删除原先的图片

步骤:

1.先上传一个普通的gif图片上去,然后在上传一个图片马gif,将上传后的jif的图片保存下来,对比两个的图片(如下),查看那里没有被渲染,对比后发现在图片的头部没有被渲染(content-type:img/gif下面的位置,可以从00开始对比,好比较些),然后在这中间插入一句话木马

普通gif

渲染后的gif

写入位置

成功访问

Pass-18-白名单验证,条件竞争

通过代码提示发现文件上传后会先在存在缓存文件中,然后在判断删除,但是这个地方有个时间差,可以利用这个时间差来执行操作,一直请求不断上传,这样我们就可能在没有删除之前读取到文件,然后向服务器写入一个shell

1.首先上传一个php木马脚本,抓取

2.将其请求包,发送到intruder模块,定义一个变量,遍历请求上传

3.浏览器一直刷新如果成功写入的访问地址,总有一次会成功解析访问

Pass-19-白名单验证,图片马

此关卡跟上一关卡一样,同样是条件竞争,但是此关卡的是需要通过上传图片木马,然后不断的通过文件包含访问图片木马

Pass-20-黑名单验证,点号绕过

Pass-21-白名单验证,数组绕过

  1. 验证过程:先检查MIME,通过后检查文件名,保存名称为空的就用上传的文件名。再判断文件名是否是array数组,不是的话就用explode()函数通过.号分割成数组。然后获取最后一个,也就是后缀名,进行白名单验证。不符合就报错,符合就拼接数组的第一个和最后一个作为文件名,保存。

  2. 绕过过程:绕过MIMIE,改一下包的Content-Type,为了绕过explode()函数,需要传入数组,绕过白名单,由于取的是end()也就是数组最后一个,需要传入数组的最后一个为jpg|png|gif,最后是拼接文件名,取的是reset()第一个,即索引为0,和索引count()-1(数组内元素个数-1)。所以令索引0为1.php,索引2为jpg(只要是索引1之后都可),这样数组元素个数为2,拼接的就是索引0和索引1,也就是1.php和空,结果还是1.php,这样就可以使得拼接后的文件名为1.php。如下:

image-20210224191355599

image-20210224192159314

成功上传

image-20210224192316286

Windows特性

上传不符合Windows 文件命名规则的文件,Windows会自动去除非法字符

.php::$DATA

.php(空格)

.php.(空格)

.php.(空格).

.php::$DATA……

.php:1.jpg

.PHP

.phpphp

文件上传防御

  1. 文件扩展名服务端白名单校验

  2. 文件内容服务端校验

  3. 上传文件重命名

  4. 隐藏上传文件路径

  5. 文件上传的目录设置为不可执行

  6. 单独设置文件服务器的域名

  7. 图片二次渲染

参考链接