目錄
1. 文件上傳漏洞簡介
2. 文件上傳漏洞的危害
3. 文件上傳漏洞的觸發條件
1. 文件必須能被服務器解析執行
2. 上傳目錄必須支持代碼執行
3. 需要能訪問上傳的文件
4. 例外情況:非腳本文件也可能被執行
4. 常見的攻擊手法
4.1 直接上傳惡意文件
4.2 文件擴展名繞過
4.3 解析漏洞利用
5. 文件上傳漏洞的防御措施
5.1 文件類型檢查
5.2 上傳路徑與訪問控制
5.3 服務器配置安全
6.phpcms文件上傳漏洞安全分析
6.1.前言
6.2.漏洞情況
第一關:初代 PHPCMS 頭像上傳漏洞
第二關:FineCMS 的補丁與再次繞過(競爭條件漏洞)
?編輯
第三關:利用隨機數生成目錄名漏洞
第四關:新補丁
正確的修復方式
結論
1. 文件上傳漏洞簡介
2. 文件上傳漏洞的危害
3. 文件上傳漏洞的觸發條件
要成功利用文件上傳漏洞,攻擊者上傳的后門文件需要滿足以下關鍵條件:
1. 文件必須能被服務器解析執行
攻擊者上傳的惡意文件必須符合服務器的運行環境。例如:
- 如果服務器運行的是 PHP 環境,則攻擊者需要上傳
.php
文件。 - 如果服務器運行的是 JSP 環境,則需要上傳
.jsp
文件。 - 如果服務器運行的是 ASP.NET,則
.aspx
文件可能有效。
示例:
如果目標服務器只支持 PHP,而攻擊者上傳的是 Java Webshell(.jsp
),即使上傳成功,服務器也無法解析執行,攻擊仍然無效。
2. 上傳目錄必須支持代碼執行
即使上傳了可執行腳本,文件存儲的路徑也必須是可執行目錄,否則服務器不會解析代碼。
- 可執行目錄: 服務器會解析
.php
,jsp
,asp
等腳本,并執行其中的代碼。 - 非可執行目錄: 服務器會將腳本文件當作普通文本處理,無法運行惡意代碼。
示例:
如果 Web 應用將上傳的文件存放在 /uploads/
目錄,并且 Nginx 或 Apache 已經配置禁止該目錄執行腳本,那么即使攻擊者上傳了 shell.php
,服務器也不會解析并執行其中的代碼,攻擊失敗。
3. 需要能訪問上傳的文件
通常,上傳文件成功后,服務器會返回上傳文件的訪問地址。如果攻擊者無法訪問這個地址,文件上傳漏洞也無法被利用。
示例:
- 如果服務器存儲路徑是
/var/www/uploads/
,但外部無法訪問該目錄,即使攻擊者上傳了 Webshell 也無法觸發它。 - 如果文件上傳成功,但服務器未返回文件訪問路徑,攻擊者無法得知上傳文件存放在哪里,除非能通過其他漏洞(如目錄遍歷)找到它。
4. 例外情況:非腳本文件也可能被執行
某些情況下,即使上傳的不是腳本文件,也可能被服務器錯誤解析,從而執行惡意代碼。例如:
- 圖片馬(圖片木馬):攻擊者上傳一張
.jpg
或.png
圖片,但圖片的元數據中隱藏了 PHP 代碼。如果服務器存在解析漏洞,可能會執行隱藏代碼。 - 配置錯誤的 Web 服務器:某些中間件(如 Apache、Nginx、IIS)可能存在解析漏洞,使非
.php
文件也會被當作 PHP 代碼解析。
4. 常見的攻擊手法
4.1 直接上傳惡意文件
攻擊者利用未做任何安全限制的上傳接口,直接上傳如 .php
、.jsp
、.asp
等可執行腳本。
4.2 文件擴展名繞過
攻擊者使用以下方式繞過服務器對文件后綴的限制:
- 雙重擴展名(如
shell.php.jpg
) - 大小寫繞過(如
SHELL.PHP
) - 空格或特殊字符繞過(如
shell.php.
) - MIME 類型偽造(通過修改
Content-Type
偽造合法文件)
4.3 解析漏洞利用
不同 Web 服務器對文件解析方式不同,可能導致繞過擴展名檢查。例如:
- Apache 服務器:支持
.htaccess
配置文件,攻擊者可以上傳.htaccess
文件修改解析規則。 - IIS 服務器:
shell.asp;.jpg
可能仍會被解析為.asp
。 - Nginx 解析漏洞:某些版本可能會錯誤解析
.php/
文件。
5. 文件上傳漏洞的防御措施
5.1 文件類型檢查
-
采用白名單機制,僅允許上傳安全的文件類型,如
.jpg
、.png
、.pdf
等。 -
驗證文件擴展名,避免使用雙重擴展名(如
shell.php.jpg
)繞過檢測。 -
檢查 MIME 類型,防止攻擊者偽造文件類型。
-
使用文件內容分析工具(如
fileinfo
)檢查文件實際類型。
5.2 上傳路徑與訪問控制
-
存儲文件時重命名,避免使用用戶自定義的文件名。
-
限制上傳目錄的權限,確保其不可執行(例如通過
Nginx
配置disable_php
)。 -
采用分離存儲策略,將上傳文件存放在與 Web 目錄隔離的存儲服務器上。
-
避免返回完整的文件路徑,降低攻擊者利用漏洞的可能性。
5.3 服務器配置安全
-
禁止執行上傳目錄中的腳本,如
Apache
配置.htaccess
限制 PHP 解析。 -
禁用危險函數,如
eval()
、exec()
,防止遠程代碼執行。 -
開啟 WAF(Web 應用防火墻),檢測并攔截惡意上傳行為。
-
定期掃描上傳文件,發現并刪除可疑文件。
6.phpcms文件上傳漏洞安全分析
6.1.前言
PHPCMS 曾經是國內流行的 CMS 之一,但因安全漏洞頻發,給廣大站點帶來了嚴重的安全隱患。其中,頭像上傳漏洞尤為經典,不僅影響 PHPCMS 本身,還波及了大量借鑒其代碼的 CMS,如 FineCMS。
6.2.漏洞情況
第一關:初代 PHPCMS 頭像上傳漏洞
PHPCMS 頭像上傳功能的邏輯如下:
-
用戶上傳 ZIP 壓縮包。
-
服務器解壓 ZIP,并刪除非 JPG 文件。
漏洞代碼片段:
漏洞點分析
-
解壓后僅刪除 ZIP 根目錄中的非法文件,但未遞歸刪除文件夾中的非法文件。
復現步驟如下:
- 攻擊者可上傳 ZIP 包,其中包含 test?目錄,并在其中放置
web.php
,繞過刪除機制。
第二關:FineCMS 的補丁與再次繞過(競爭條件漏洞)
FineCMS 修復代碼:
利用時間差上傳 ZIP 文件,其中包含如下代碼:
<?php fputs(fopen('../../../../../shell.php','w'),'<?php phpinfo();eval($_POST[a]);?>');?>
在服務器解壓 ZIP 并執行刪除操作的瞬間,攻擊者訪問 webshell,實現 Getshell。
復現步驟如下:利用burp抓包,然后通過不停發包與刷新,訪問php文件,讓他在上級或者其他級目錄生成惡意代碼
第三關:利用隨機數生成目錄名漏洞
為了防止競爭條件攻擊,開發者修改了代碼,使上傳的文件存放在隨機命名的目錄中。然而,新機制未能正確處理解壓失敗的情況,導致 Webshell 仍然可能被上傳。
復現步驟如下:
- 構造一個解壓失敗的壓縮包。
- 讓 PHPCMS 處理解壓失敗,但部分文件仍然被釋放到 Web 目錄。
- 由于目錄刪除機制缺陷,Webshell 仍然得以保留。
如何構造解壓失敗的壓縮包
第四關:新補丁
-
頭像文件解壓至隨機命名的目錄。
-
發生錯誤時,立即刪除臨時目錄。
代碼示例:
繞過方法:路徑穿越攻擊(Directory Traversal)
構造 ZIP 文件,修改其內部文件名,如
../../../index.php
。利用 Notepad++ 修改 ZIP 內部文件路徑,上傳后覆蓋網站根目錄的
index.php
,實現 Webshell。
正確的修復方式
以上漏洞的根本問題在于:
-
不應直接在 Web 目錄下解壓用戶上傳的文件。
-
應使用白名單方式限制解壓文件。
-
避免使用 Zip 方式上傳頭像,改用前端處理。
安全修復方案:
-
將 ZIP 文件解壓到臨時目錄(如 /tmp)。
-
僅提取合法的 JPG 文件,其他文件一律忽略。
-
對解壓縮的文件進行嚴格 MIME 類型檢測。
-
采用白名單方式,避免黑名單的局限性。
結論
PHPCMS 頭像上傳漏洞的演變歷程,展現了補丁打補丁的錯誤思路。正確的修復方法應從設計上避免問題,而不是簡單地對抗攻擊者的新手法。開發者應深刻理解文件上傳的安全風險,避免重蹈覆轍。
僅僅是技術分享,不要再審核卡我啦