题目
|
|
Solution
源代码如下:
接下来逐步分析。目标是让v1,v2,v3都为 1,这样才能得到flag。
v1
|
|
传入的foo,经过一次json_decode,然后转换成array。然后判断 $a["bar1"]
是否满足 is_numeric,若满足则die掉。接下来又判断 $a["bar1"]
是否大于 2016 。
利用php弱类型特性,可以设置
这样is_numeric时会判断其为字符串而不是数字,而在与2016的比较中,会直接转换成2017,满足大于2016。这样 v1 就被设置为 1 了。
v2
|
|
接下来,要求$a["bar2"]
是个数组,其中元素的个数为5个(count($a[“bar2”])!==5),同时要求$a["bar2"][0]
是数组。所以我们设置:
对于 $pos = array_search("nudt", $a["a2"]);
,它搜索字符串“nudt”在$a[“a2”]中的位置。若没有找到,array_search返回false,会通过严格比较导致die掉。所以这里要设置:
注意这里因为用了$pos===false?
的严格比较,所以0不===
false。
之后就能设置 v2 = 1
结合$a是由json_decode得来,所以第一个payload为:
v3
|
|
先会用strcmp进行比较,利用数组array和字符串进行strcmp比较会返回null,而且数组array也不会等于字符串,我们可以设置cat[1]为一个数组。
接下来用eregi对拼接后的字符串$d.$c[0]
进行正则匹配,若匹配到则die掉。而下一步又要求拼接字符串$c[0].$d
中要有字符串“htctf2016”。这里利用%00对eregi的截断功能,则在正则匹配eregi时在开头时就匹配结束掉。
strpos(($c[0].$d), "htctf2016")
中,还要求“htctf2016”不能出现在开头。
所以设置:
所以综上所述,构造总的payload如下:
得到flag: