Thinkphp <= 5.0.10 缓存getshell复现

Thinkphp <= 5.0.10 缓存getshell复现

0x01 poc

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

1077935-20190724232301899-2052379398.png

然后会生成以下缓存文件

1077935-20190724232308127-1310053909.png

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

1077935-20190724232312765-1718682128.png

1077935-20190724232317724-1258099832.png

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

1077935-20190724232322455-1634076104.png

1077935-20190724232328443-1197315233.png

1077935-20190724232333460-1636087533.png

0x02 跟踪源码

1077935-20190724232338714-1179555309.png

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

1077935-20190724232343981-766879320.png

跟进self::init()

1077935-20190724232353614-1245814598.png

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

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

1077935-20190724232359630-1534740019.png

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

1077935-20190724232405192-757958073.png

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

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

1077935-20190724232410935-857024524.png

继续回溯

1077935-20190724232434858-1621250331.png

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

1077935-20190724232441019-1987345507.png

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

1077935-20190724232446004-794766846.png

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

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

1077935-20190724232453306-2119952236.png

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

0x03 审计思路

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

0x04 补丁

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

1077935-20190724232459211-1781267487.png

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

0x05 参考

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

转载于:https://www.cnblogs.com/litlife/p/11241571.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值