typecho反序列化利用链分析
[toc]
上次国赛有一道这个题,baby_serialize,看了好久也没做出来,感觉自己代码审计能力太差了,于是乎想找几个cms审审反序列化的链子,于是就有了这篇。
找的是typecho1.1的那个漏洞,呜呜呜太菜了,因为是第一次,还是一边看师傅博客一边完成的,此处膜拜P3师傅。因为现在的版本漏洞已经修复了,搭环境还浪费了好长时间,真的心累。
利用条件
漏洞利用的地方是在install.php,这里只是验证了一下有没有get提交finish参数,若没有则退出,有的话再继续往下进行,先看看利用点:
1 | <?php else : ?> |
这里把从get中数据然后base64解码然后再反序列化,看一下get方法的实现:
这里用了一个三目运算符,如果cookie存在就从cookie中获取值,否则就从POST参数获取值。这里我们只要直接通过cookie或者post传入我们的payload就可以利用此次漏洞。
反序列化利用链构造
因为这里是 unserialize 函数,首先我们肯定要找 __destruct() 魔术方法来利用反序列化,结果看了一圈也没有一个能用的,然后又全局搜索了 __wakeup() 方法,也是没有可以利用的。
然后往下看,new了一个 Typecho_Db 类,看看这个类的 __construct 。
db.php 114-120行:
可以看到这里用了字符串拼接操作,在这里可以触发 __toString() 方法,然后全局搜索__toString,在feed.php中发现可利用点。
feed.php 258-259行:
这里的 item['author']->screenName 可以触发 __get() 方法,然后全局搜索get方法,然后会在request.php中发现可以rce的get()方法。
首先是
request.php 269-272行:
这里调用get函数,跟进
request.php 295-311行:
这里在最后会调用_applyFilter
方法,看看这个方法
request.php 159-171行:
就会调用这里的call_user_func()执行函数。还要说的一个地方就是,当按照上面的所有流程构造poc之后,发请求到服务器,却会返回500。
原因是在install.php的开始,调用了 ob_start() ,当我们在执行的时候会触发原本的exception,导致ob_end_clean()执行,原本的缓冲区被清理。必须像一个办法下强制退出,使得代码不会执行到exception,这样原本的缓冲区数据就会被输出出来。
这里有两个办法。 1、因为call_user_func函数处是一个循环,我们可以通过设置数组来控制第二次执行的函数,然后找一处exit跳出,缓冲区中的数据就会被输出出来。 2、第二个办法就是在命令执行之后,想办法造成一个报错,语句报错就会强制停止,这样缓冲区中的数据仍然会被输出出来。
解决了这个问题,整个利用POP链就成立了
poc:
1 | <?php |
成功执行:
修复方法
若是之前的版本只要删掉install.php就好了,看看官方的修复方法:
增加了对数据库的判断,原来finish被删掉了,这样就安全多了。
- Post Title: typecho反序列化利用链分析
- Post Author: Katharsis
- Post Link: http://yoursite.com/2020/09/03/typecho-1-1/
- Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.