[鹤城杯 2021]EasyP

<?php
include 'utils.php';

if (isset($_POST['guess'])) {
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) {
        $message = 'Congratulations! The flag is: ' . $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__);
}
?> 

 这个题目出现了$_SERVER['PHP_SELF']

这个是你调用的脚本的路径

比如说这个题目它的值就是/index.php

如果你访问的是

http://1.14.71.254:28189/index.php/utils.php

那么它的值就会是/index.php/utils.php

而$_SEVER['REQUEST_URL']

它的值这个时候和$_SERVER['PHP_SELF']的值是一样的,

区别在于,如果你用get传参的时候$_SEVER['REQUEST_URL']是会加上那个参数的,而$_SERVER['PHP_SELF']不会。

 

然后是basename这个函数。

这个函数是返回最后面一个/后面的名字。

 

这个函数有一个可以利用的地方就是,如果传入的参数中出现了非ascii字符则会把它给丢弃。

 

最后是讲绕过正则

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

 

 这个正则的绕过方法就是利用特性来绕过,可以用

 [

  (空格)

 +  

 .

上面那几个字符任何一个都行,都可以被处理成_

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

 

这个正则是匹配末尾有没有utils.php/

绕过办法很简单

因为后面要调用basename,所以可以利用中文来绕过,中文不属于ascii编码中的,所以可以payload

 

posted @ 2022-07-02 20:18  FPointmaple  阅读(967)  评论(0编辑  收藏  举报