BUUCTF-WEB之[HarekazeCTF2019]encode_and_encode

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

分析

$body = file_get_contents('php://input');//PHP 输入流中获取请求的主体内容
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>';
}

if判断有三个条件:
1、检测传入的内容是否合法也就是is_valid(),传入的内容里面不能含有非法字符,但是没有过滤filter协议
2、传入的格式就是json格式
3、传入的参数就是page
三个条件同时满足的话就会通过file_get_contents得到该文件

$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{&lt;censored&gt;}', $content);
//这里不绕过的话flag会被覆盖掉,因此使用filter伪协议来绕过(将内容进行base64加密后flag就不会被覆盖了)

因为要读取flag文件,但是is_valid()函数将flag和php都过滤了,所以这里还有一个知识点就是:

php的json_decode在遇到unicode编码时会自动把它转换成正常的字符

那么将php://filter/read=convert.base64-encode/resource=/flag进行Unicode编码
789
789
然后将flag进行解码。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信