thinkphp5.0.23 invokefunction RCE漏洞 详细分析与复现

您所在的位置:网站首页 RCE漏洞利用方法 thinkphp5.0.23 invokefunction RCE漏洞 详细分析与复现

thinkphp5.0.23 invokefunction RCE漏洞 详细分析与复现

2024-01-03 08:33| 来源: 网络整理| 查看: 265

本文为thinkphp5.0.23 invokefunction 漏洞 RCE 详细分析与复现。

复现

去官网下载thinkphp5.0.23

漏洞payload ?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami本地搭建环境实测XDEBUG_SESSION_START是调试用的,不用管s参数是thinkphp的一种路由形式http://xxx.com/index.php?s=/module/controller/func/args/value (func也叫action,就是类里的方法名)

举个小例子例如s=index/index/getname/name/z3

漏洞分析

现在来分析下payload中的s参数s=index/think\app/invokefunctionmodule 是 index,对应的是index文件夹controller 是 think\app,对应的是???func 是 invokefunction,对应的是 think\app的invokefunction方法

上面例子中s=index/index/getname/name/z3,是application/index/controller/Index.php文件中的getname方法,但是think\app是什么,controller文件夹下找不到

那只能调试一下,看thinkphp是如何解析路由的从index.php开始看

index.php->/../thinkphp/start.php->/base.php

然后执行了App::run()->send();

先看App::run()方法看注释是一些框架初始化的操作,继续往下看是处理路由的操作调试可以看出,routeCheck将路由解析了进去看一下跟进parseUrl调用了parseUrlPath方法,使用trim,根据/ 进行分割,得到数组

然后就是对路由的解析了path的第一个元素定义为module第二第三元素定义为controller和action,然后返回又回到了App.php的run方法,知道了controller就是think\php,但还不知道怎么调用的think\php继续看调用了execmodule方法执行了命令,跟进创建了request对象设置request的module设置moduel路径

下面重点又来了,解析controller :think\app

一番操作后,controller还是think\app,

Loader::controller成功解析了think\php注意看$instance是think\App类型对象

App.php里果然有invokeFunction方法,所以继续调试,应该就是通过反射,获取到call_user_func_array方法的反射对象,传参调用

再看下payload:

&function=call_user_func_array &vars[0]=system &vars[1][]=whoami

这里传入的函数是call_user_func_array参数是[system,[whoami]]即$reflect->invokeArgs([system,[whoami]])注意这里$reflect->invokeArgs方法参数是一个数组,而call_user_func_array第一个参数是函数名,第二个参数也是数组,这就可以理解为什么要这样构造了&vars[0]=system,&vars[1][]=whoami

还有个问题没解决Loader::controller怎么解析的think\php跟进Loader::controller方法跟进ReflectionClass通过ReflectionClass方法创建了think\App对象

试一下正常调用

s=index/index/getname/name/z3

controller 应该是index,被解析为了app\index\controller\Index那为什么think\app没有被解析为app\index\controller\think\app呢?

再重新调一遍,在Loader::controller中,index被解析为了app\index\controller\Index

继续跟进getModuleAndClass方法问题就在这里,如果匹配到了\,$class就原封不动,还是think\app。如果没匹配到\,进入parseClass方法将class的路径补全为app\index\controller\Index

总结

所以现在知道了thinkphp5.0.23 invokeFunction漏洞的原理

thinkphp在解析controller时,如果有\字符,就原封不动的用它来创建对象,所以将controller设置为think\php,就会创建App对象

而App对象里有invokefunction方法,所以action设置为invokefunction

invokefunction参数是调用的函数名和参数,所以可以执行任意方法了

本质就是可以根据项目代码中的class创建对象,并调用对象的方法,并且可控参数。

思考

实战中遇到的几个问题。例如module名不确定,可能是index、admin、home等等如果module名不对,就会报错原因是module初始化时,会检查application文件夹下有没有module的文件名,如果不存在,就会抛出异常解决办法

暴力尝试

在thinkphp5.0之前版本可以使用?m=index&c=index&a=index方式指定module,controller,action,那么?c=index&a=index,不指定m,就会使用默认module

如何修复

看5.0.24修复方法很直截了当,用正则做了个过滤,不会绕。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3