ThinkPHP 命令执行漏洞-01 – 作者:fightzhong

前言

ThinkPHP 官方 2018 年 12 月 9 日发布重要的安全更新,修复了一个严重的远程代码执行漏洞。该更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的 getshell 漏洞
受影响版本:5.x < 5.1.31, <= 5.0.23

漏洞分析

thinkphp 实验版本:5.0.20
首先,先看看一下官方给出的补丁信息:
fa0905d7492fe003de8e05c17b874c2e.png
大概猜测到这个漏洞是由于框架没有对控制名进行足够的检测导致的。
poc:
http://localhost:8888/index.php?s=index/think\App/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

当index.php加载thinkphp框架引导文件后,会执行应用,即执行think\App::run()方法,\表示将App作为类名来调用,payload正是利用此特性来调用任意类的方法。
6d01532aea3f615a0c328551f4efd4f2.png
根进run()中的路由检测方法routeCheck()
d82563f4e1ee7a0209b82619f62fe6b0.png
会获取pathinfo信息,
11a078a3409ac053bb72ade7118b5f3f.png
由于配置文件中’var_pathinfo’的值默认为’s’,所以该pathinfo()函数会获取GET请求中’s’对应的值,在这边也就是
index/think\app/invokefunction
之后,Route::parseUrl()方法调用parseUrlPath(),只是通过‘/’做分割,并未做过滤。
113b240a614bbd7b96cd5964bed183ab.png
获取当前的调度信息后,会执行调用分发函数exec()
657adbb0745313b29682ca93e2c9187f.png
这边传入exec的调度信息参数$dispatch为:
aaee85708888e3ab2e23638cdc1fb2d0.png

根进module方法,即执行模块
c62ba7cd9e2963c743957718f0673cd8.png
该模块获取控制器名为:”think\app“,该处并未对控制器名做过滤。
根进Loader::controller方法,该函数主要作用是实例化控制器,调用getModuleAndClass解析出$module和$class的值分别为“index”和“think\app”,再调用App::invokeClass($class)对$class进行实例化,回到App::module()方法,获得实例化放射类“think\App”后,执行反射类的方法
9eb6cdc2d63ec2254042eb319439e506.png
跟进invokeMethod,可以看到该方法将运行call_user_func_array函数,
4a174055af115443011ade8e86f9b22a.png
返回system(‘whoami’)的结果
5af49f9b13ddb972f67e04ec02df0d94.png

漏洞补丁

Thinkphp v5.0.x 补丁地址:https://github.com/top-think/framework/commit/b797d72352e6b4eb0e11b6bc2a2ef25907b7756f
Thinkphp v5.1.x 补丁地址:https://github.com/top-think/framework/commit/802f284bec821a608e7543d91126abc5901b2815

来源:freebuf.com 2019-07-28 17:23:48 by: fightzhong

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论