能登入 SSH 的站長,處理 PHP2Shell 時先做三件事:找出網站真正使用的 PHP、在正確位置套用臨時緩解、更新 PHP 並重啟對應工作程序。下面以 Ubuntu 24.04、APT 安裝的 PHP 8.3-FPM 為完整操作例子,另說明寶塔及 Docker 的分流;路徑與服務名稱要跟自己的環境核對,不能整篇不看就貼上。
PHP 官方已在 2026 年 10 月 21 日修補 CVE-2026-109618 與 CVE-2026-109619。上游修補版是 8.2.35、8.3.36、8.4.27、8.5.12。發行版可能回移修補,請比對完整套件版本;例如 Ubuntu 24.04 的公告修補版為 8.3.6-0ubuntu0.24.04.13。
登入 SSH 後,先看 PHP 是誰安裝的
先執行以下唯讀命令。它們用來找線索,尚未改動設定或更新套件:
cat /etc/os-release
command -v php
php -v
php --ini
ps -eo pid,ppid,args | grep '[p]hp-fpm'
systemctl list-units --type=service --all | grep -E 'php.*fpm|apache2|httpd'
php -v 和 php --ini 顯示的是命令列 PHP,未必是網站的 PHP。還要對照網站的 Nginx/Apache 虛擬主機設定、FastCGI socket,以及對應 FPM master 的啟動路徑。寶塔可能使用自己的 PHP 目錄;容器內的 PHP 也不會隨宿主機的 APT 更新。
若已確認使用 Ubuntu 的 PHP 8.3-FPM 套件,再查套件與服務:
dpkg-query -W -f='${binary:Package}\t${Version}\n' 'php8.3*'
apt-cache policy php8.3-common php8.3-fpm
systemctl show php8.3-fpm -p ExecStart -p MainPID
記下安裝來源、完整版本、FPM 服務名稱與網站連到的 pool。維護前保存網站檔案、資料庫及 PHP/Web 設定的可還原備份,安排短暫中斷時段;同一 FPM 服務可能承載多個網站。
臨時關閉 session.upload_progress,要改哪裡?
要關的是 session.upload_progress.enabled。PHP 官方要求在請求解析前已生效的 php.ini、FPM pool 或伺服器設定中調整,之後重新啟動每個相關工作程序。不要把 ini_set() 加到網站程式裡,也不要依賴 FPM 的 .user.ini 完成這項緩解。
在已確認使用標準 Ubuntu PHP 8.3-FPM、會讀取 /etc/php/8.3/fpm/conf.d/ 的例子中,可新增一份獨立設定;若同名檔已存在,先備份及閱讀,避免蓋掉別人的內容:
sudoedit /etc/php/8.3/fpm/conf.d/99-php2shell.ini
檔案內容只放這一行:
session.upload_progress.enabled = 0
若由特定 FPM pool 統一管理,可由維護者改用該 pool 內的 php_admin_flag[session.upload_progress.enabled] = off;先檢查現有設定及覆寫關係。不要在所有 PHP 目錄做全機搜尋取代。
確認設定無誤後,先測試配置,通過才重啟;兩個步驟分開執行,測試失敗就停止:
sudo /usr/sbin/php-fpm8.3 -t
# 上一個命令成功,才執行以下兩行
sudo systemctl restart php8.3-fpm
sudo systemctl status php8.3-fpm --no-pager
這會停用 PHP 的 session 上傳進度追蹤,依賴它的進度顯示可能受影響,並不等於禁止所有檔案上傳。更重要的是,它只封住已確認的部分 session 攻擊路徑;PHP2Shell 還有其他路徑,不能把畫面顯示 Off 當成漏洞已修復。
Ubuntu APT 安裝的 PHP,怎樣升級?
以下仍限同一個 Ubuntu 24.04/PHP 8.3-FPM 例子。先更新套件索引,再看候選版本;若來源沒有公告中的修補版本,先處理來源、套件鎖定或供應商更新,不要把執行成功當成已有補丁:
sudo apt update
apt-cache policy php8.3-common php8.3-fpm
apt-mark showhold
sudo apt install --simulate --only-upgrade php8.3-common php8.3-cli php8.3-fpm
閱讀模擬結果,確認沒有意外移除套件,並盤點網站已安裝的 PHP 擴展。下面三個名稱只是核心與 CLI/FPM 範例;若另外安裝 MySQL、curl、mbstring 等擴展,應把實際使用的對應套件一起列入更新及驗證範圍。--only-upgrade 不會替你安裝原本沒有的 FPM。
sudo apt install --only-upgrade php8.3-common php8.3-cli php8.3-fpm
dpkg-query -W php8.3-common php8.3-cli php8.3-fpm
sudo /usr/sbin/php-fpm8.3 -t
# 配置測試通過後,更新所有本服務工作程序
sudo systemctl restart php8.3-fpm
sudo systemctl status php8.3-fpm --no-pager
套件更新可能自行重啟服務,仍要確認實際結果。這是同分支修補,不會把 7.2 自動變成 8.3;跨分支遷移需要另做應用程式與擴展相容性測試。若網站用 Apache 的 mod_php,對應的是 Apache 服務與模組套件,不能照抄 FPM 的路徑或只重啟 Nginx。
寶塔、自行編譯和 Docker,要走自己的更新路線
面板管理或自行編譯的 PHP,先核對正在使用的二進位檔與安裝前綴,再從原供應商取得修補建置或升級方案。宿主機執行 apt upgrade,通常不會替另一套安裝目錄的 PHP 打補丁。面板顯示「8.3」也不夠,應取得完整版本或供應商對兩個 CVE 的修補說明。
Docker Compose 若使用供應商預建映像,先確認新映像已包含修補;以下假設服務名稱為 php,在自己的 Compose 專案目錄執行。若鎖定舊 digest,要先更新為核實過的修補 digest,否則 pull 仍會取得舊版:
docker compose pull php
docker compose up -d --no-deps php
docker compose exec php php -v
pull 只下載映像,並不更新正在運行的容器;up 才會依變更重建服務容器。若是自己的 Dockerfile,需以修補過的基底重新建置映像,再部署該映像。先確認持久化資料與回退版本,不需要為更新 PHP 執行 down -v。
最後要驗網站的 PHP,不只看命令列
用網站既有的受限診斷功能,或只允許管理者存取的短暫檢查頁,讀取以下值。完成後移除檢查頁;不要公開完整 phpinfo(),也不要把設定路徑截圖貼到公開地方:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo 'version=', PHP_VERSION, "\n";
echo 'sapi=', PHP_SAPI, "\n";
echo 'ini=', php_ini_loaded_file(), "\n";
echo 'upload_progress=', ini_get('session.upload_progress.enabled'), "\n";
只有在存取限制已由 Web 伺服器或其他獨立機制生效時才放置這個頁面。upload_progress 可能以 0 或空字串表示關閉;這只確認設定,不證明漏洞已修補。版本仍須與供應商套件公告一起核對,並確認各個 PHP 服務、pool 與容器的舊工作程序都已替換。
再測首頁、登入、表單與原有上傳流程,查看 PHP/Web 錯誤紀錄。發生 502 或功能異常時保留錯誤,按配套備份回退;不要為了消除錯誤,直接把未修補的服務重新暴露給所有訪客。沒有補丁又無法確認安全時,應先限制外部存取,交維護者安排遷移。

評論0