• Thinkphp <= 5.0.10 缓存getshell复现


    Thinkphp <= 5.0.10 缓存getshell复现

    0x01 poc

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

    然后会生成以下缓存文件

    可以看到,字符串abc直接存储到以php结尾的缓存文件中。尝试使用 换行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行的thinkcachedriverFile类。然后在51行进行实例化,并return。

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

    继续回溯

    这里调用了return过来的实例的set方法。跟进thinkcachedriverFile的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

  • 相关阅读:
    msyql 死锁
    yii2 操作数据库
    yii2 加载静态资源
    Yii2 之 UrlManager 实践 (一)
    Wordpress 之 Rewrite Rules
    yii2 使用gii生成代码文件
    权限设计的杂谈
    NodeJS —— 自定义流的实现
    浅析递归
    请将你的App签名文件放进保险箱
  • 原文地址:https://www.cnblogs.com/litlife/p/11241571.html
Copyright © 2020-2023  润新知