夜间模式暗黑模式
字体
阴影
滤镜
圆角
主题色
Typecho 反序列化漏洞复现
本文最后更新于 121 天前,其中的信息可能已经有所发展或是发生改变。

0x01 漏洞分析

在typecho 的 install.php文件中,有这么一段代码:

可以看见调用了Typecho_Cookie类中的get方法,获取名为__typecho_config的Cookie,并且经过base64解码后再进行反序列化,并把最后的值给了$config变量。

随后取出$config['adapter']$config['prefix']实例化了一个对象 ,跟进,在db.php中:

这里没别的东西了,于是就去寻找 __toString魔术方法: 在Feed.php 的第233行。

可以看到,该方法首先是对RSS版本作了判断,执行相应的操作,在 359行处发现了这样一段代码:

上述代码中,如果在screenName属性是私有的或是不存在的情况下去调用它 ,会触发__get魔术方法,于是我们全局搜索__get方法,发现在Request.php文件中

跟进get()方法:

发现最后调用了_applyFilter方法,继续跟进:

如果我们能够控制call_user_func函数中的两个参数 $filter $value,那么就能够实现任意命令执行。

0x02 POP链构造

进入漏洞触发点

  1. Install.php
  2. $_GET[‘finish’] == 0
  3. Referer: 本站host

漏洞利用链

Install.php new Typecho_Db($config['adapter'], $config['prefix']); ===>

Db.php $adapterName = 'Typecho_Db_Adapter_' . $adapterName; $adaoterName即为传入的 $config[adapter] 控制 $config['adapter']为对象 触发 __toString ===>

**Feed.php ** __toString方法: 控制$_type === ATOM 1.0走到:<name>' . $item['author']->screenName . '</name> ,设置$item['author']为对象,掉哟screenName ,若不存在,则触发__get 魔术方法 ===>

Request.php __get调用 get($key, $default = NULL) ,传入参数key给数组 $_params,并且在此给$value赋值,随后调用_applyFilter方法,跟进 ===>

Request.php call_user_func($filter, $value); 为任意命令执行处,通过数组 $_filter控制函数名,数组$_params控制函数参数,即可完成命令执行。


根据上述pop链构造初步payload

将以上payload输出后传入Cookie,发现报500数据库错误

image-20190605120143742

发现在install.php中有:

因为我们之前的对象注入,触发了exception ,执行了ob_end_clean() 使得我们的输入被清空,无法回显。

因此我们需要让代码在执行完命令执行函数后,停止往下运行。可以采用两种方法:

1.控制call_user_fun处遍历的数组,使得我们第二次执行的函数时执行到某个可以调用exit()的函数,使程序退出。

2.在命令执行之后,想办法造成一个报错,语句报错就会强制停止,这样缓冲区中的数据仍然会被输出出来。

image-20190605121941730

使用第二种方法,在上图处提前触发报错,从而得到回显。

完整poc

暂无评论

发送评论 编辑评论


				
上一篇
下一篇