码迷,mamicode.com
首页 > Web开发 > 详细

Thinkphp <= 5.0.10 缓存getshell复现

时间:2019-07-25 00:17:01      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:条件   null   shel   tca   return   实例化   生成   就是   场景   

Thinkphp <= 5.0.10 缓存getshell复现

0x01 poc

首先看缓存函数的使用场景

技术图片

然后会生成以下缓存文件

技术图片

可以看到,字符串abc直接存储到以php结尾的缓存文件中。尝试使用\n换行getshell

技术图片

技术图片

语法有错,注释一下后面的垃圾字符,成功getshell。

技术图片

技术图片

技术图片

0x02 跟踪源码

技术图片

首先跟进18行的Cache::set()函数

技术图片

跟进self::init()

技术图片

self::$handler此时为null,进入true块,由于上面调用的是self::init(),没有参数,故67行条件不满足。

69行,查看配置cache.type的值,发现默认为File,

技术图片

故此条件也不满足,进入72行。此处以上图的cache数组作为参数,调用了self::connect()。跟进connect方法

技术图片

这里通过一系列判断,根据cache.type的值,找到cache驱动为File,对应44行的think\cache\driver\File类。然后在51行进行实例化,并return。

回溯到上个函数,也直接return

技术图片

继续回溯

技术图片

这里调用了return过来的实例的set方法。跟进think\cache\driver\File的set方法

技术图片

可以看到,在142行调用了getCacheKey方法。

技术图片

跟进getCacheKey方法后发现,这里由于options[‘cache_subdir‘]默认值是true,所以这里直接用参数md5加密后的结果的前两位作为目录名,剩余30位作为缓存文件名。然后通过拼接.php后return。

继续回来,获取上面构造的filename之后,在146行将$value进行序列化,然后在149行使用gzcompress对其进行二进制压缩。接着在151行在data前后拼接php标签,最后在152行写文件。

技术图片

这里存在漏洞的点就是151行把用户可控的数据放到了php标签内。

0x03 审计思路

拿到源码后,找到Cache::set(name, value, expire),其中缓存文件名是跟name相关联的,因此可以看作是一个已知条件。漏洞的关键点就是value是否可控。

0x04 补丁

看一下修复之后的结果(v5.0.15)

技术图片

这里在data之前加了一个exit()强制退出,基本杜绝了data执行php代码的可能。

0x05 参考

ThinkPHP 5.0.10-3.2.3 缓存函数设计缺陷可导致 Getshell

Thinkphp <= 5.0.10 缓存getshell复现

标签:条件   null   shel   tca   return   实例化   生成   就是   场景   

原文地址:https://www.cnblogs.com/litlife/p/11241571.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!