第一关
查看源码,开启题目第一关:
这很明显是要让我们绕过的,但是怎么绕呢?
$_SERVER[‘QUERY_STRING’]就是意思是直接检测你url?,就是?后面的所有
第一个if判断语句,如果获得的参数QUERYSTRING里存在 ‘‘ 这个字符则直接die出局,并且%5f就是他的unending编码也给ban了。
这不禁让我回忆起之前在一篇文章中提到的一个特殊情况关于php特殊字符转下划线
这里面哪个是利用点呢?
经过测试后发现,’+’,’ ‘(空格),’.’都可以转义为下划线,但是上文提到的]却不行,我也不知道为啥。。。
参数名搞定了,还有参数值呢?要我们匹配到不全等于2333,又要匹配23333开头23333结尾。
用%0a进行绕过吧。第一关就这样通过了
第二关
一进来说我们的ip被ban了,只有本地才能访问
既然刚刚网页源码有提示,我们也看看这个有什么吧
我又想到一个东西。。在攻防世界里有个fuck啥的东西,在网页控制台可以解析。
让我们post一个Merak过去。。
POST过去后得到一长串的php代码
第三关
源代码如下
前面也分析了只有本地才能访问,所以这里给了我们一个getIp函数去调取我们的ip是否等于127.0.0.1,这里无所谓,因为我们用burp抓包修改xff或者client-ip都可以绕过这个判定条件
下面的file_get_contents($_GET[‘2333’])这个点的意思是我们传入一个2333的参数,file_get_contentes是将整个数据读入一个字符串中。这在我写过的一个伪协议的引用[ZJCTF 2019]NiZhuanSiWei中有个知识点提到
所以也就是php://input和data://都可以进行写入。
那我们如何选择呢?其实我用得比较多的是php://input,但是如果看过上面这个文章就发现不太对劲了。为什么?上面文章写到的是只有一个参数,也就是
但是我们现在还有post一个参数是merak,所以这样比较尴尬,我上传不了(或者说我不会),所以这次我们使用data://来上传。
**2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=**
用心观察的人会发现,他包含了了一个flag.php,那大胆猜测flag就在这个flag.php里了
file_get_contents()可以帮助我们显示文件的内容,那么现在有个问题来了,这change函数是干啥用的。
解释一下change函数的两个核心
chr() 函数从指定的 ASCII 值返回字符。
ASCII 值可被指定为十进制值、八进制值或十六进制值。八进制值被定义为带前置 0,而十六进制值被定义为带前置 0x。
ord() 函数返回字符串的首个字符的 ASCII 值。
首先定义用法,然后将变量进行base64解码(这说明后面POST参数file的值必须先进行base64编码),然后通过一段for循环,这段for循环的作用是先将字符转换为ASCII码,再将ASCII码逐步+$i*2
,$i
初始值为0,然后再转回字符
其中strlen函数作用是计算字符的数目,chr是把ASCII转成字符,ord是把字符转成ASCII数字
经过对照ASCII码表和计算,我们需要传递到file参数的值为“fj]a&fb(flag.php经过change函数转换为fj]a&fb)”的base64值,也就是ZmpdYSZmXGI=
(可费劲了。。)
所以,我们最终提交的两个get参数为
记得把merak这个参数去掉,不然会被die出去
然后查看源码即可