php复杂变量的应用
前言
这道题主要是在做南溟师傅的学弟出的题时碰到的,后续还做了2019年De1的题中碰到过,所以想要记录下学习的历程。
题目
原题长这个样子:
1 |
|
第一次看到这个题目时,我的理解就是这里$str直接被拼接入eval所以可以直接执行代码,直接”;你的代码;$a1=”即可获取到flag.php的内容。
一些扩展
但是有些地方还是值得思索的,例如有没有什么办法能直接回显flag.php中的变量?并且我们可以再加入一个限制,比如禁止使用单引号和双引号,
1 | eval('$a="' .addslashes($str) . '";'); |
这个点我以前也在实战中遇到过一回,所以特别记忆犹新,那个利用点是可以写配置的,然后有类似:
1 | fwrite('\$m="'.some_filter_function($_global['m']).'""'); |
当时没想到解决方法,就找了另外的点getshell,但现在看来还是操作一下的。
关于复杂变量的理解
例如这道题给出的预期解就是${system(print_r($flag))}
,如何理解呢?
在此之前,我们先做个直观的实验
双引号中可以解析带$符号的变量,而像{}
也会导致同样的结果,也就是说$紧挨着{可以将字符串解析为变量。并且,在括号中表达式执行的优先级是较高的,所以就有:
我们来理解下这个式子,${system(print_r($flag))}
,我们反着理解整个过程。
首先最内层解析$flag,
然后解析print_r($flag),
我们查到print_r实际上是有返回值的,这就好办了,system(print_r($flag))能被解析,实际上这里就是$a=print_r($flag); system($a);这样的式子,
当然报错还是会报错的。最后${}解析里面的整个表达式,最后作为变量赋值给$a
这里我们回过头来看看实战中碰到的点,我们的目标是getshell。
那么整个antsword的shell也是可以的。$m= {$_POST[1]};$m1=${@eval(${m})};,即可getshell。1=phpinfo();
总结
php一些性质还是比较有意思的,比如伪协议什么的,做题还是碰到不少的,以后多看看。