[HarekazeCTF2019]encode_and_encode
[HarekazeCTF2019]encode_and_encode
考点
PHP在json_decode时会自动解码传入的Unicode编码
wp
Source Code给了源码
<?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]);
file_get_contents('php://input')
获取 post 的数据,json_decode($body, true)
用 json 格式解码 post 的数据并返回数组,然后 is_valid($body)
对 post 数据检验,大概输入的格式如下

is_valid($body)
对 post 数据检验,导致无法传输 $banword
中的关键词,也就无法传输 flag
,这里在 json 中,可以使用 Unicode 编码绕过,flag
就等于 \u0066\u006c\u0061\u0067
通过检验后,获取 page
对应的文件,并且页面里的内容也要通过 is_valid
检验,然后将文件中 HarekazeCTF{}
替换为 HarekazeCTF{<censored>}
,这样就无法明文读取 flag
这里传入 /\u0066\u006c\u0061\u0067
后,由于 flag
文件中也包含 flag 关键字,所以返回 not found
,这也无法使用 file://

file_get_contents
是可以触发 php://filter
的,所以考虑使用伪协议读取,对 php
的过滤使用 Unicode
绕过即可

最后更新于