命令执行php框架代码,ThinkPHP远程命令执行漏洞原理及复现

2018年12月11日,exploit-db更新了一个thinkphp框架远程代码执行漏洞

exploit地址:https://www.exploit-db.com/exploits/45978

由于框架对控制器名没有进行足够的检测导致在没有开启强制路由的情况下getshell

漏洞影响范围

Thinkphp 5.1.0 - 5.1.31

Thinkphp 5.0.5 - 5.0.23

安装:

下载地址http://www.thinkphp.cn/donate/download/id/1125.html

下载完解压在/var/www/html/目录下即可

42745de615a86badb7e0720d6f43c126.png

漏洞分析

/thinkphp/library/think/App.php 行数:120

4cc280ac150d9209fccaf0aae15881c8.png

我们可以看到通过self::routerCheck函数进行路由检测

c8e642b8fe928305b833c5a09cbd87ed.png

我们可以看到又进入$request->path()函数

/thinkphp/library/think/Request.php 行数:416行

efdcaf2277ccdaccf82fcab55d069cb3.png

进入pathinfo()函数,继续追踪到384行

a04bb724be288ab3aa4b2f717950c684.png

Config::get('var_pathinfo')是配置文件中的设置的参数,默认值为s,从GET中获取键值,然后赋值给routeCheck中的$path

我们再回到App.php 行数:606

07f75f45847f99da41b92481caae3b34.png

这里会进行路由检测,检查$check后会进入else分支导入路由配置,接着检测路由url调度结果为$result,如果调度失败且开启了强制路由$must,则报出路由无效,接着进入Route::parseUrl函数,根据$path(自定义url)解析操作

开始跟踪parseUrl函数

/thinkphp/library/think/Route.php 行数:1208

2ff774d6674ac30cf6970158db3a119d.png

进入parseUrlPath函数 行数:1275

787acf09683dd6e4ff54843382fa8079.png

这里我们可以看到对模块/控制器/操作的url地址分割成数组来返回(没截好图有点重了)行数:1217

195a44a4aceafbc3050d79ff67a9017a.png

1767136598a425be029c05c43a9799ec.png

我们可以看到,返回的结果赋值为$path,提取路由信息又封装到$route,最后返回

thinkphp/library/think/App.php 行数:120

f43edea58cb2a82e77d7a0af98714262.png

进入self::exec函数 行数:445

6b56c51986deb0c09e0c16f9b9e419f8.png

我们可以看到模块/控制器/操作 的函数为self::module

开始跟踪module函数 行数:494

e12e95f22378b8fef80f5ff1030dd2c1.png

e7ad67f6c4e715c9176a8e8bcd2cfd2f.png

我们可以看到,根据$config['app_multi_module']进入多模块部署,$bind为NULL,又进入elseif分支,判断模块是否在禁止的列表里面$config['deny_module_list'],而且mmodule存在,$available = true,就不会抛出异常

module函数最后的返回值,发现$controller没有进行过滤,那么此时应该为think\app,也就是return self::invokeMethod($call, $vars);

d855d3f150dfd1541ef038409bb8202a.png

进入self::invokeMethod函数 行数:329

3076e1bf906af1ebed2fc980a226b7ce.png

此时穿进去的$call也就是$method,是一个数组,第一个元素是一个think\App对象,第二个元素则是调用方法名称的字符串invokefunction,然后通过反射ReflectionMethod获取这个对象下对应的方法

再通过函数$args = self::bindParams($reflect, $vars);获取传入的参数,也就是payload

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值