你有没有发现,这里没有要求v1和v2不相等......
这里涉及到两个美元符\$\$,这种变量叫可变变量,最直观的理解:
输出结果是world,\$\$a就相当于是\$(\$a)=\$hello。
我们可以发现要想输出最终的flag变量,要满足两个foreach和一个if,先看一下这个if,它要求post的flag值与已知flag变量相等,这显然是无法做到的。因为一旦flag值被传入,第二个foreach就会执行\$\$key=\$\$value,使得\$flag发生改变,这样flag就输不出来了。
所以最终的解决办法是触发if条件,修改error,也就是将error修改为flag。但注意我们无法直接传入error=flag,因为get和post都限制了值,所以需要转换一下:
GET: ?suces=flag POST: error=suces
搞定。
居然是接104的,这回限制了v1和v2不相等,像md5一样找0e吧。用104的hint:
aaK1STfY 0e76658526655756207688271159624026011393 aaO8zKZF 0e89257456677279068558073954252716165668
首先介绍parse_str(string, array)函数:string字符串会传入一组或多组键值对,将其解析并保存到array中。eg:
parse_str("a=1&b=2", $arr)
此时arr数组就是{"a"=>1, "b"=>2}这种字典对应。
所以这个题非常简单了,payload:
GET:
v3=1
POST:
v1=flag=c4ca4238a0b923820dcc509a6f75849b
搞定。
ereg函数存在00截断漏洞,可以用a%00匹配正则,之后需要翻转化整数,0x36d的十进制是877,倒转传入即可,payload:
?c=a%00778
能直接echo类,说明这个类一定有_toString方法,找到符合条件的异常类Exception以及反射类ReflectionClass。
php有类似于python的函数式编程,\$a='phpinfo',那么\$a()就相当于phpinfo(),进行函数调用。
v2这里传个语句进去会先执行再报错。payload:
?v1=Exception&v2=system(ls) ?v1=ReflectionClass&v2=system(ls)
还是这样的过滤,这回用FilesystemIterator类,析构方法的参数是目录,我们用getcwd方法获取当前目录传入FilesystemIterator遍历当前目录下文件。
除此之外可以用DirectoryIterator遍历目录。发现目录下有个fl36dga.txt文件,事实上我们可以直接访问这个文件,不需要千方百计去读取它的内容。
看着getFlag就像是个赋值并输出,v1要有ctfshow,那就传一个ctfshow,主要是输出v2的值,题目中也没有任何明显提示,就只能GLOBALS把所有全局变量全输出来,正好var_dump是可以输出数组的。
?v1=ctfshow&v2=GLOBALS
有个过滤器filter,过滤掉了一些东西,先不管它,主要是后面的is_file判断,要求传入的file不是文件,但还能highlight_file,这就要说明is_file和highlight_file对于文件的判断:is_file认为伪协议不是文件,highlight_file认为伪协议是文件,所以这里传入filter伪协议即可。至于flag具体在哪,就试一试吧,比如flag.php。
过滤了filter,放出了input,那就input。可以去查一查各种php封装和包含的协议,挨个看看能不能用,实际上这里使用zlib可以输出。Hint给出的目录溢出会使is_file判断其不是文件,而highlight_file会正常识别。
又把filter放出来了,直接读即可。