thinkphp v5.0.23 rce 复现

Buchiyexiao.
  • thinkphp是一个轻量级的框架,其中在thinkphp5版本中出现了很多命令执行漏洞,本文分析采用的代码使用的是thinkphp版本v5.0.23(目的是匹配docker搭建的thinkphp环境的版本)

  • 漏洞位置

    thinkphp5的主要漏洞位置位于处理请求的Request类中,其中存在method方法,简单阅读发现该方法目的是为了获取当前的请求类型,因为我没有传入任何请求,所以get,post等的数组为空

    在这里插入图片描述

    其中var_method是一个表单请求类型伪装变量,官方文档中存在该变量的解释和说明https://www.kancloud.cn/manual/thinkphp5/160568

    通过阅读官方文档我们可以发现,_method变量同时在函数内没有做任何的过滤操作,因此我们可以通过更改和控制_method变量的值来调用Request类中的方法

    我们寻找到Request类的构造方法

    在这里插入图片描述

    重点是在foreach里面,如果数组键值的键存在以此命名的属性,那么就进行赋值操作,所以我们可以借助foreach来完成覆盖

    因此我们需要寻找一个调用了request中method方法的方法,发现在路由route的check方法中用到了method方法
    在这里插入图片描述

    我们尝试进行漏洞的触发

    在这里插入图片描述

    因为我们控制了filters参数,所以后续理论上可以执行system函数,但是运行完之后会发现filter被清零了,从system变成了空

    在这里插入图片描述

    逐步执行发现其存在filter的过滤机制

    在这里插入图片描述

    这样导致我们无论如何对filter进行赋值,最后执行的时候的命令都为空,所以需要新的函数去触发漏洞

    我们发现Request中的param也调用了method方法,同时参数为true,进入server方法,然后再跳入input方法

    在这里插入图片描述

    这里可以发现input方法将key值为requset_method的成员取出赋值放入filtervalue,同样,数组我们是可控的,所以我们需要找到调用param方法的地方

    我们手动开启debug模式

    在这里插入图片描述

    因为如果我们开启debug模式的话,那么我们就可以执行param()

    在这里插入图片描述

    payload: POST _method=__construct&filter[]=system&server[REQUEST_METHOD]=ls

    和之前构造的payload基本类似

    但是服务器中我们不能更改debug

    所以我们可以发现在开启debug模式下执行param,如果不开启则不进入循环就去执行exec,上图中最下面

    exec通过对$dispatch[‘type’]进行switch来判断调用什么方法,其中controller和method都调用了param方法,因此我们需要对dispatch进行分析,发现其定义在一个routeCheck方法,我们对该方法进行分析,发现result是用到了Route的check方法,发现其调用了method,同时我们注意到此处调用的strtolower

    在这里插入图片描述

    是刚才逐步执行后filter的值,说明我们的整体思路是正确的

    thinkphp中有一个验证码的第三方库,在被加载的时候会注册一条路由规则,由于这条规则是直接路由到控制器类的方法,所以type为method,所以就可以顺着执行上面的代码了,因此仿照上面的payload进行构造

    在这里插入图片描述

    payload : _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls

    xxx/?s=captcha

    ls在windows下没办法展示,但是该命令是执行的

    在这里插入图片描述

    在linux下搭建环境后执行该payload

    在这里插入图片描述

    如果是写shell的话,改ls为file_put_contents(‘1.php’,’<?php phpinfo();?>’)即可

  • 防御方法和测试的过程心得

    • 对method和_method进行过滤

      在这里插入图片描述

      我们可以对method进行多一轮的判断,比如判断其是否具有get,put,delete,patch,post等参数,同时也可以漏洞点也是因为对_method变量的缺乏过滤,所以可以对该变量进行函数名的判断

    • 最开始的时候看给出的参考链接可以发现其版本补丁修改的位置,也就可以找到补丁所对应的版本存在的漏洞

      在这里插入图片描述

      https://github.com/top-think/framework/commit/4a4b5e64fa4c46f851b4004005bff5f3196de003

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐