第六届金盾信安杯Web题解
比赛一共4道Web题,比赛时只做出三道,那道文件上传没有做出来,所以这里是另外三道题的WP
分别是 fillllll_put hoverfly ssrf
fillllll_put
涉及:
绕过exit() 死亡函数
php://filter 伪协议配合base64加解密
一句话木马
题目源码:
$content参数在开头被拼接了exit函数,需要绕过exit()函数才能使得通过$content参数写入的文件内容被成功执行而不是直接执行exit函数,可以用base编码实现绕过
详解php://filter以及死亡绕过_filter绕过过滤-CSDN博客
就是利用php://filter/write=convert.base64-decode来对文件中的内容先进行base64解码
比如下面这行代码
file_put_contents('php://filter/write=convert.base64-decode/resource=1203.php', 'SGVsbG8gV29ybGQ=');
write=convert.base64-decode指定了一个写入过滤器,该过滤器会在数据被写入之前对其进行 Base64 解码
所以当执行这行代码时,PHP 会先对 SGVsbG8gV29ybGQ=
进行 Base64 解码,得到 Hello World
,然后将这个解码后的字符串写入到1203.php文件中
base64编码中只包含64个可打印字符,PHP在解码base64时,遇到不属于这64个字符之外的字符时,将会忽视这些字符,进行把符合范围的字符重新组成一个新的字符串然后解码
写入文件中的内容为 <?php exit(); 加上后面拼接$content参数,可以拼接一句话木马,比如<?php eval($_POST[a]); 进行base64编码得到 PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==
在base64解码的过程中 "<?php exit();" 里面只有phpexit 这七个字符在base64编码表中,所以能够被解码的字符仅有phpexit,其他的字符会被忽略,base64算法解码时是4字节一组,这里七个字符phpexit无法进行解码,所以可以随便添加一个字符a,凑齐8个字节就可以被base64解码,得到
这样就让exit()函数失去了作用完成绕过,$content参数后面构造的一句话木马会被成功解码并识别为php代码
构造Payload:
(任何没有以 read=
或 write=
作前缀 的筛选器列表会视情况应用于读或写链,所以可以不加write=)
?filename=php://filter/convert.base64-decode/resource=1.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==
连接蚁剑之后在/tmp/flag.txt文件下找到flag
hoverfly
浏览器搜索发现hoverfly存在漏洞,搜集信息之后发现可以命令执行和任意文件读取
但是读取文件需要知道文件名,使用搜集到的payload尝试读取flag文件
在/flag和/tmp/flag都读取到了flag但是都是假的flag
手动猜测文件名得到flag的可能性太低,换思路,尝试命令执行
Payload是下面这种格式
同时发现题目页面中的信息刚好能够对应上图的命令中的信息,如下图所示,所以进行命令执行
先执行ls命令发现成功回显文件信息
接下来直接用 grep -r 命令遍历目录查找文件中的关键词flag即可得到flag
在/tmp/fa1g文件中得到flag
ssrf
题目提示是ssrf,而且界面也很像ssrf
测试一下,输入 www.baidu.com 虽然没成功回显,但是查看页面源码得到提示
加上http:// http://www.baidu.com 成功访问到百度主页
那么直接配合file协议读取一下本地文件/etc/passwd
提示:不允许使用 file://、gopher:// 或 dict:// 协议
使用file://被过滤,而刚才传入http://时成功回显没有过滤,所以判断是file://这一部分被禁止输入,而不是单独的file或者 ://
猜测代码中是使用preg_match()函数进行过滤的,尝试用反斜线\ 分隔file://来绕过代码的检测
输入file:\///etc/passwd 成功读取
接着读取/flag.txt失败,回显False,说明给出的信息可能是错的
目录扫描发现flag.php
测试路径之后得到是/var/www/html/flag.php 输入 file:\///var/www/html/flag.php
成功得到flag.php源码
进行代码审计,只要绕过if判断让$ip和127.0.0.1比较的结果相等即可执行后面的代码输出flag
这里127.0.0.1是被禁止的,传入http://127.0.0.1/flag.php,会提示Invalid URL!
但是如果把127.0.0.1改为127.0.0.2,会发现能够直接得到flag
多次测试发现在127.0.0.2到127.9.9.9范围内取值都是可以得到flag的,而127.0.0.0和127.0.0.1不行,第一位如果不是127的话也不行
那么输入http://127.0.0.2/flag.php
或者http://127.0.0.2/falg1111111111111111111111111111l1.txt都可以得到flag,只要前面的格式在127.0.0.2到127.9.9.9范围即可