[鹤城杯 2021]EasyP

题目可在NSSCTF平台复现:NSSCTF

这是一个恶心的题,恶心到做过的人也不愿意把wp写的细化,看了一圈wp发现基本都只给个payload,细节什么的也基本没写,让人摸不着头脑。我来讲讲吧!!

 

这个题骚就骚在看似简单的一串代码给你搞几个不认识的变量,然后再搞个你不认识的函数,最后还弄个没用的一串代码迷惑你,然后吓得一些人就不敢动笔了。在做题前我们先了解了解几个陌生的东西(对我而言)。

陌生一:$_SERVE['PHP_SELF']

$_SERVE[‘PHP_SELF’] 读取的是当前执行脚本的文件名,意思就是读取文件夹下的一个文件如,

如下即为执行脚本的文件:

www.errorr0.com/errorr1/errorr2/        ------     /errorr1/errorr2/index.php

www.errorr0.com/errorr1/errorr2/index.php   --------   /errorr1/errorr2/index.php

www.errorr0.com/errorr1/errorr2/flag.php    ---------  /errorr1/errorr2/flag.php

www.errorr0.com/errorr1/errorr2/index.php?key=value    --------  index.php

[鹤城杯 2021]EasyP_第1张图片

[鹤城杯 2021]EasyP_第2张图片

[鹤城杯 2021]EasyP_第3张图片

 [鹤城杯 2021]EasyP_第4张图片

简单来说,若原本在为www.errorr0.com/errorr1/errorr2/index.php的正常情况下,若想办法将url弄成www.errorr0.com/errorr1/errorr2/index.php/flag.php,最后通过$_SERVE[‘PHP_SELF’]后,会得到/errorr1/errorr2/index.php/flag.php

陌生二:$_SERVER['REQUEST_URI']

$_SERVER['REQUEST_URI']是取得当前URL的 路径地址,直接测试一下看看和上面一个的区别,

[鹤城杯 2021]EasyP_第5张图片

[鹤城杯 2021]EasyP_第6张图片

[鹤城杯 2021]EasyP_第7张图片  

很简单理解就是剔除域名剩下的就是我们所谓的URL路径地址,无论后面的数据请求是否正确都成立。

陌生三: basename()

不多说,我是菜鸟直接看菜鸟教程,

[鹤城杯 2021]EasyP_第8张图片

 [鹤城杯 2021]EasyP_第9张图片

 [鹤城杯 2021]EasyP_第10张图片

[鹤城杯 2021]EasyP_第11张图片

大概含义我们可以理解为最后一个“ / ”后的所有数据。

解题

OK我们看完了这几个陌生的知识做题看着也会舒服一些,接下来分析一下题目,迎面给了一串代码:

if (isset($_POST['guess'])) {
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) { //$secret不知道是哪来的,所以这一串代码没有什么用,有也只为了让我们头疼的。
        $message = 'Congratulations! The flag is: ' . $flag; //看似flag,实则坑人
    } else {
        $message = 'Wrong. Try Again';
    }
}

所以这一串代码纯纯是恶心人来的。

重点还是下面:

if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
    exit("hacker :)");
}

if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");
}

if (isset($_GET['show_source'])) {
    highlight_file(basename($_SERVER['PHP_SELF']));
    exit();
}else{
    show_source(__FILE__);
}

highlight_file可以起到文件读取的作用,而我们第一行代码就有个utils.php的文件包含,所以大胆猜测flag就在这个文件中(当然,我做过肯定是知道就是在里面,不用猜)。

所以接下来我们有两件事情要做,一件事绕过正则是使show_source不为空,另一件事是使basename($_SERVER['PHP_SELF'])值为utils.php,即使$_SERVER['PHP_SELF']******/utils.php,最后basename这个值就会为utils.php再然后就highlight_file读取到文件。

所以我们要想办法绕/utils\.php\/*$/i 以及/show_source/这个正则匹配,

[鹤城杯 2021]EasyP_第12张图片

只要在后面加个非ASCII码的东西就可以绕过。

[鹤城杯 2021]EasyP_第13张图片

 所以我们用%88或者只要是可以造成乱码的url编码就可以绕过/utils\.php\/*$/i 正则匹配。

/show_source/show[source或者show.source绕过,这个记住即可。

所以最终我们构造出来的payload为:

/index.php/utils.php/%88?show[source=1

参考:PHP basename() 函数 | 菜鸟教程

PHP 中的 $_SERVE['PHP_SELF'] 的一个注意点_ckx_cxy的博客-CSDN博客_php_self

你可能感兴趣的:(刷题+WP,安全,web安全,php,后端)