刚上线的PHP项目被攻击了怎么办
写在前面
最近真的有点忙,同时做着4个项目
,对接客户,沟通需求,技术造型,搭建项目框架,设计后端接口,定义对接流程,编写文档,督促前端partner,每一项都要亲力亲为,所以代码质量难免有折扣。这不,一不小心,就爆了。。。项目刚上线就被攻击了,幸好没有造成损失!
问题表象
昨天下午,我打开项目后台,发现直接跳到了项目首页
,我以为是有哪个地方有重定向,或是登陆状态有误,才会跳到了项目首页,连续试了几个url,都是如此,所以就登陆服务器看了一下,发现public/index.php
被修改了,并且public/vendor/laravel-admin/
下面多了几个文件,当时也没多想,直接把文件恢复了,多出来的文件也删除了,以为是客户误操作,所以他们才没有唠叨
我。
结果今天下午,我再次打开项目后台,还是直接跳到了项目首页
,还是不管什么url都会跳到了项目首页,这才意识到可能是被攻击
了,于是登录服务器确认,昨天删除的文件又重新产生了,public/index.php
又被修改了。心里虽然骂娘,但是问题还是得解决。
初步解决
因为问题的表象是public/index.php
被修改,所以我想到的第一个操作就是,不让它修改,于是直接就给它"上锁
"了,如下
chattr +i public/index.php
这样做虽然可以防止public/index.php
被修改,但是没有查到根本原因,就无法解决根本问题。本着尽职尽责的态度,晚上又接着往下看这个问题了。
继续追踪
根据以往的经验来说,这种问题,一般都是通过上传文件接口把病毒植入到服务器上来的,于是就查看了nginx
的access_log
,果然发现了几个可疑
的请求,如下
,果然发现了几个可疑
的请求,如下
3605:127.0.0.1 - - [05/May/2025:16:42:26 +0800] "GET / HTTP/1.1" 200 832 "http://www.seocx.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"3616:127.0.0.1 - - [05/May/2025:16:52:54 +0800] "GET /storage/avatars/1_1745770882.php HTTP/1.1" 200 4289 "https://xxx.com/tags.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"3624:127.0.0.1 - - [05/May/2025:16:53:44 +0800] "GET /vendor/laravel-admin/AdminLTE/bootstrap/css/bootstrap.php HTTP/1.1" 200 2204 "https://xxx.com/tags.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"3626:127.0.0.1 - - [05/May/2025:16:53:57 +0800] "POST /tags.php HTTP/1.1" 200 3066 "https://xxx.com/tags.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
第一个www.seocx.net
在浏览器上打开一看,应该是seo网站,所以问题应该不是它。
第二个storage/avatars/1_1745770882.php
显然问题就大了,因为storage/avatars
是存放用户头像的目录,不可能有php
文件,而且这种命名就是通过上传头像产生的。
第三个bootstrap.php
就是多出来的文件之一。
第四个tags.php
并不存在,应该是一种轮询测试方式,也是有问题的。
故不难看出,漏洞
就是第二个请求产生的,或者说漏洞
与第二个请求有直接关系。查看相关代码,如下
$member_id = auth('api')->id();
$file = $request->file('avatar');
$folder_name = "storage/avatars";
$upload_path = public_path() . '/' . $folder_name;
// 获取文件的后缀名,因图片从剪贴板里黏贴时后缀名为空,所以此处确保后缀一直存在
$extension = strtolower($file->getClientOriginalExtension()) ?: 'png';$fileName = $member_id . '_' . time() . '.' . $extension;
// 将图片移动到我们的目标存储路径中
$file->move($upload_path, $fileName);
此处我们没有判断文件的后缀,用户就利用了这个漏洞上传了带有攻击性的php
文件。
修改起来也不困难,增加一下文件后缀的判断即可
,如下
if( !in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'heic']) ) {Log::error('50006 --> illegal attacking');return response()->json(err('图片格式不正确'));
}
本来问题到这就算解决了,但是带攻击性的php
文件名是1_1745770882.php
,从上面的代码可以看出,1_1745770882.php
开头的1
是member_id
,而且第一个用户一般要么是开发人员
,要么是客户
,又不是无间道,两者皆不可能上传病毒文件,所以还得继续往下看。
回到登陆
由于申请小程序帐号,需要使用企业主体,所以很多流程我们是无法代劳的,只能客户自己完成申请,需要一定的时间。所以登陆的时候,为了快速测试
,我做了一个特殊
的登陆方式,如下
if( $request->jscode == 'test' && env('FOR_APP_SESSION_KEY') == true ) { $data = ['session_key' => 'test_session_key_000000000000001','openid' => 'test_openid_000000000000001',];
} else {$wechat = Factory::miniProgram($config);$data = $wechat->auth->session($request->jscode);
}
意思就是当.env
配置文件里面的FOR_APP_SESSION_KEY
等于true
时,jscode
传test
就会模拟平台接口的返回,然后拿到的member_id
就是1
。攻击都就是利用了这个登陆方式,成功登陆了。
这个终归还是我的问题,没有及时将.env
配置文件里面的FOR_APP_SESSION_KEY
改掉。于是改掉配置之后,又删除了此用户,并且为了确保万无一失,又在middleware
里面增加了判断,如下
if( auth('api')->id() == 1 ) {Log::error('50005 --> ',[$request->all(), $request->header()]);return response()->json(err(50005, 'Invalid user'));
}
检查无误
这个问题的产生,就是由于当时大意
,
- 1. 没有及时修改配置,关闭特殊登陆方式
- 2. 没有检查用户上传的文件的后缀
所以就再三检查了
本次的修复
步骤
- 1. 使用
chattr
设置文件不可修改 - 2. 检查用户上传的
文件的后缀
,只能是图片类型 - 3. 关闭
特殊登陆
方式 - 4. 删除
member_id
为1
的用户 - 5. 禁止
member_id
为1
的用户访问