本文最后更新于:2019 , 八月 19日 星期一, 1:17 下午
漏洞描述
影响版本:v1.1 ~ 15.5.12 及以前的版本
该漏洞发生在 install.php文件中,在参数 __typecho_config中我们可以传入一些构造数据
使程序进行一系列的操作,最后由call_user_func()
函数 或者 是 array_map()
实现任意代码执行
Code 分析
文件: install.php
![](/images/PHP/代码审计/typecho 反序列前台getshell/0.png)
在这 我们发现 __typecho_config
参数是可控的
经过 base64 解码
再进行反序列化 最终赋值给 $config
然后往下看到了 一个实例化类的操作 new Typecho_Db
这里我们想是否 能利用 这个实例化类的操作
触发一些魔法函数,再看这些魔法函数中是否有一些危险函数
这里最有可能触发的 就是 __construct()
这个魔法函数
__construct()
触发条件:当一个对象被创建时调用的
文件: Db.php
我们在整个源码中搜索 __construct()
函数
发现 Db.php文件 调用了 __construct() 函数
![](/images\PHP\代码审计\typecho 反序列前台getshell\1.png)
这里可以 看到并没有什么可以直接利用的危险函数
可是,这里执行了一个字符串拼接的操作(字符串拼接一个变量的操作)
adapterName 对应 config 里面的adapter
如果我们用 adapter
来实例化一个类,PHP是弱类型的语音把一个字符串和类拼接的时候会强制把类转换成字符串,这个时候就会触发 __toString 方法
__toString()
的触发条件:把类当作字符串使用时触发
文件:Feed.php
接下来就是搜索__toString()
函数
在Feed.php文件中发现了__toString()函数
在这函数中 并没有发现可以直接利用的函数或参数
于是对代码进行分析
发现 $item
是 $this -> _items
的 foreach 循环
出来的
并且 $this -> _items
是Typecho_Feed类 的 一个private属性
在这里如果可以将 $item['author'] 定义为一个类
而该类中未定义screenName变量
当执行到 290行 $item['author'] -> screenName
时
则会自动调用__get()
魔法函数
__get()
触发条件:用于从不可访问的属性读取数据
文件:Request.php
接下来我们就 需要 寻找一个类中有 __get()魔法函数,并且这个函数中有可利用的危险函数
发现 Db.php文件 调用了 __get() 函数
发现 __get()函数 进行了一系列的操作之后 进入_applyFilter
函数
发现 这个函数中 调用了两个可以执行任意代码危险函数array_map()
call_user_func()
接下来我们 看下危险代码的函数的参数是否 可控
发现_filter
参数,在文件刚开始就定义了
说明这是可控的
而 $value
参数是 通过_params
获取的 然后通过 __get()方法一系列操作之后 传入_applyFilter
函数的
于是我们搜索_params
,发现也是可控的
整个过程
数据的输入点为 install.php 文件中的参数 _typecho_config,从外部读入我们构造的序列化数据
是程序会进入类的 Typecho_Db类的 __ocnstruct()函数,然后进入 Typecho_Feed类的 _toString()函数
再依次进入 Typecho_Request类的 __get() ==> get() ==> _applyFilter()函数
最后由 call_user_func() 或 array_map() 函数实现任意代码执行
漏洞复现
漏洞复现条件
1.在 install.php 文件开头声明了 必须要有 finish
参数才可以进行下一步操作
2.这里拦截了跨站请求,说明referer
需要是本站才行
在install.php 调用的Typecho_Cookie 这里类中发现不仅可以cookie访问,还可以post访问
这里我就不写poc了,因为我这里只是对漏洞进行复现,学习思路,做下笔记
就直接进行漏洞复现了