虽然自己也水了些CVE,但是并没有自己满意的、漂亮的漏洞利用链,今天呢主要是自己还没审出过反序列化漏洞,所以找了typecho老版本来审一下。
正文
在install.php第246行会反序列化操作

进Typecho_Cookie类看一下get方法

这里很显然是一个获取值的。继续看一下怎么进入到这个反序列化,这里php夹杂着html代码,不太方便看,我简单处理一下。首先

这里是判断是否已经安装的,一般其他cms的写法是只判断是否已经存在了lock文件,但是这里有个可控参数,也就是我们还能进入这个install.php页面。继续往下走,可以直接进入反序列化操作。这里还需要魔术方法,可以参考我总结的另外一篇文章http://p0desta.com/2018/04/01/php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%80%BB%E7%BB%93/

这里我首先跟的是 $db->addServer,但是当我跟到 Config.php第62到81行的时候

只发现到这里如果类当做数组遍历的时候会触发 cureent方法,但是我全局搜 current方法并没有找到可以利用的地方。
然后继续跟一下

跟到 Db.php第114行到135行

危险的地方在于

因为 $adapterName方法是可控的,被当做字符串拼接了,那么就会触发 toString方法,简化一下

那么全局搜一下toString找一下可以利用的地方
找到这个跟进去,这里看Feed.php第290行

读取不可访问属性的值时,get() 会被调用,那么只要item['author']我们可控,那么就可以出发get()魔术方法。
通过全局搜素 __get()跟进/var/Typecho/Request.php,267行

继续看get方法

接着调用了 _applyFilter方法,继续跟进


一开始我直接构造getshell,并没有遇到什么问题,但是如果想讲执行结果输出出来就会遇到问题,问题产生的原因呢在于
install.php第54行 ob_start();
看一下手册
什么意思呢,这里我写个小demo来解释一下

这个执行的话是不会有输出的, ob_start()激活了缓冲,输出结果会被写入到缓冲区,但是如果执行了ob_end_clean函数就会把缓冲区的内容丢弃掉,那么也就没有输出了。在Common.php第225行

设置了用户自定义的异常处理函数,当存在未捕获的异常时会调用,看一下定义测函数

@ob_end_clean();显然,它清理了缓冲区。
这里因为payload使我们构造好带进去的,很难做到不触发异常,那么我们有什么办法来绕过呢。这里我想到的是让它执行完我们的命令之后引发个报错,看一下报错类型

写个demo解释一下

看Feed.php第292-296行

那么我们就可以让其停止执行,这样的话就不会执行到 ob_end_clean函数了。修改payload如下

总结
总的利用链还是非常有意思的

有趣的攻击链总能引起研究的兴趣。
本文仅用于普及网络安全知识,提高小伙伴的安全意识的同时介绍常见漏洞的特征等,若读者因此做出危害网络安全的行为后果自负,与合天智汇以及原作者无关,特此声明。本文为原创文章,转载请注明出处!
网友评论