payload
1 | #coding=UTF-8 |
原理
这是一个PHP序列化的漏洞
原因出在网站根目录下install.php里
1 | <?php if (isset($_GET['finish'])) : ?> |
这里可以看出,只要存在finish
,并且__typecode_config
的cookie存在,就可以对base64加密过的cookie进行序列化。
下面又把config里的adapter和prefix使用Typecho_Db进行实例化,并且调用了addServer的方法,下面,我们进入Typecho_Db瞄一瞄:
当然序列化后的对象,我们无法直接调用方法,所以,我们必须找一些能特殊调用的方法,比如构造函数,析构函数之类的,
这里,我们在Db.php中对象的构造函数下发现了:
1 | public function __construct($adapterName, $prefix = 'typecho_') |
这里存在一个$adapterName字符串进行了拼接,所以就能触发string()方法
我们可以全局搜素toString()方法,观察有没有我们需要的:
我们发现了这里存在问题:
1 | public function __toString() |
到这里,我们知道item[‘author’]中screenName的键值如果不可访问,就会触发__get()函数
我们再去寻找get函数:
我们寻找到一个request的对象:
1 | public function __get($key) |
这里对_params属性进行赋值,把结果传入value,最后返回_applyFilter($value),我们跟到这个函数里看看:
1 | private function _applyFilter($value) |
这里就比较的清晰明了了,array_map()可以把数组中的每个值发送到用户自定义函数,返回新的值。call_user_func 可以把第一个参数作为回调函数调用,也就是说,都可以命令执行,由于我们第二个参数是数组,所以,我们不能使用eval,那我们就使用assert来实现命令执行,最后,构造整个的序列化:
1 | <?php |
最后,得到的就是结果了。
实现一下: