thinkphp5被执行GetWebShell导致网站被反复挂木马的解决方案 [TOC] # 背景 前几日刚解决完挖矿木马,这几日服务器又中病毒,项目总是被挟持跳转到第三方彩票网站。 一开始以后是服务器问题,各种改密码,做安全策略,重新部署项目。 时隔多日后,木马再次出现,且主要更改项目/public对外目录。 前前后后处理了多次,现总结经验写下这篇博文 # 解决方案 ## thinkphp 官方漏洞 ### 描述 主要是因为官方的两个漏洞。 **2018.12.09** 由于ThinkPHP5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,黑客构造特定的请求,可直接GetWebShell。 **2019.1.11** 由于ThinkPHP5框架对Request类的method处理存在缺陷,导致黑客构造特定的请求,可直接GetWebShell。 **影响版本** ThinkPHP 5.0系列 < 5.0.24 部分5.1版本 ------------ ### 解决方案 如果有条件,还是建议更新框架到最新版本,如果调整得内容过多,可手动打入补丁,打入方法如下: #### 安全漏洞一解决方案 参考地址:[官方说明](https://blog.thinkphp.cn/869075 "https://blog.thinkphp.cn/869075") **5.0版本** 在think\App类的module方法的获取控制器的代码后面加上 ~~~ if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { throw new HttpException(404, 'controller not exists:' . $controller); } ~~~ **5.1版本** 在think\route\dispatch\Url类的parseUrl方法,解析控制器后加上 ~~~ if ($controller && !preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { throw new HttpException(404, 'controller not exists:' . $controller); } ~~~ #### 安全漏洞二解决方案 参考地址:[官方说明](https://yq.aliyun.com/articles/686397 "https://yq.aliyun.com/articles/686397") 在thinkphp\library\think\Request.php中搜索 ~~~ public function method($method = false) { if (true === $method) { // 获取原始请求类型 return $this->server('REQUEST_METHOD') ?: 'GET'; } elseif (!$this->method) { if (isset($_POST[Config::get('var_method')])) { $this->method = strtoupper($_POST[Config::get('var_method')]); $this->{$this->method}($_POST); } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); } else { $this->method = $this->server('REQUEST_METHOD') ?: 'GET'; } } return $this->method; } ~~~ 改成 ~~~ public function method($method = false) { if (true === $method) { // 获取原始请求类型 return $this->server('REQUEST_METHOD') ?: 'GET'; } elseif (!$this->method) { if (isset($_POST[Config::get('var_method')])) { $method = strtoupper($_POST[Config::get('var_method')]); if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) { $this->method = $method; $this->{$this->method}($_POST); } else { $this->method = 'POST'; } unset($_POST[Config::get('var_method')]); } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); } else { $this->method = $this->server('REQUEST_METHOD') ?: 'GET'; } } return $this->method; } ~~~ ## 开启强制路由,重视每个异常 开启强制路由,重视每个异常,这对程序的健壮性和严谨性有非常大的帮助,所以如非必要请不要随意调整错误报告级别。 ## public目录权限级别 以前是直接给予public文件夹777权限,一般public对外文件只需要给予能够运行的最低权限即可,目前我这边给到的是555,通过这种方式,木马文件无法再次生产。 ## 常备份 经常的备份才不至于在木马侵入的时候才显得手足无措。有备份后大不了关机,重做系统。 # 总结 这个问题实际处理时间超过了两周,这两周是和木马斗智斗勇,由于一开始没有经验,且对服务器安全完全不懂,导致手足无措,现将经验总结如上,希望后期可以回顾,也能帮到正在阅读文章的你。