寫在前面
最近真的有點忙,同時做著4個項目
,對接客戶,溝通需求,技術造型,搭建項目框架,設計后端接口,定義對接流程,編寫文檔,督促前端partner,每一項都要親力親為,所以代碼質(zhì)量難免有折扣。這不,一不小心,就爆了。。。項目剛上線就被攻擊了,幸好沒有造成損失!
問題表象
昨天下午,我打開項目后臺,發(fā)現(xiàn)直接跳到了項目首頁
,我以為是有哪個地方有重定向,或是登陸狀態(tài)有誤,才會跳到了項目首頁,連續(xù)試了幾個url,都是如此,所以就登陸服務器看了一下,發(fā)現(xiàn)public/index.php
被修改了,并且public/vendor/laravel-admin/
下面多了幾個文件,當時也沒多想,直接把文件恢復了,多出來的文件也刪除了,以為是客戶誤操作,所以他們才沒有嘮叨
我。
結果今天下午,我再次打開項目后臺,還是直接跳到了項目首頁
,還是不管什么url都會跳到了項目首頁,這才意識到可能是被攻擊
了,于是登錄服務器確認,昨天刪除的文件又重新產(chǎn)生了,public/index.php
又被修改了。心里雖然罵娘,但是問題還是得解決。
初步解決
因為問題的表象是public/index.php
被修改,所以我想到的第一個操作就是,不讓它修改,于是直接就給它"上鎖
"了,如下
chattr +i public/index.php
這樣做雖然可以防止public/index.php
被修改,但是沒有查到根本原因,就無法解決根本問題。本著盡職盡責的態(tài)度,晚上又接著往下看這個問題了。
繼續(xù)追蹤
根據(jù)以往的經(jīng)驗來說,這種問題,一般都是通過上傳文件接口把病毒植入到服務器上來的,于是就查看了nginx
的access_log
,果然發(fā)現(xiàn)了幾個可疑
的請求,如下
,果然發(fā)現(xiàn)了幾個可疑
的請求,如下
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網(wǎng)站,所以問題應該不是它。
第二個storage/avatars/1_1745770882.php
顯然問題就大了,因為storage/avatars
是存放用戶頭像的目錄,不可能有php
文件,而且這種命名就是通過上傳頭像產(chǎn)生的。
第三個bootstrap.php
就是多出來的文件之一。
第四個tags.php
并不存在,應該是一種輪詢測試方式,也是有問題的。
故不難看出,漏洞
就是第二個請求產(chǎn)生的,或者說漏洞
與第二個請求有直接關系。查看相關代碼,如下
$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
,而且第一個用戶一般要么是開發(fā)人員
,要么是客戶
,又不是無間道,兩者皆不可能上傳病毒文件,所以還得繼續(xù)往下看。
回到登陸
由于申請小程序帳號,需要使用企業(yè)主體,所以很多流程我們是無法代勞的,只能客戶自己完成申請,需要一定的時間。所以登陸的時候,為了快速測試
,我做了一個特殊
的登陸方式,如下
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'));
}
檢查無誤
這個問題的產(chǎn)生,就是由于當時大意
,
- 1. 沒有及時修改配置,關閉特殊登陸方式
- 2. 沒有檢查用戶上傳的文件的后綴
所以就再三檢查了
本次的修復
步驟
- 1. 使用
chattr
設置文件不可修改 - 2. 檢查用戶上傳的
文件的后綴
,只能是圖片類型 - 3. 關閉
特殊登陸
方式 - 4. 刪除
member_id
為1
的用戶 - 5. 禁止
member_id
為1
的用戶訪問