PHP 高風險 RCE 漏洞(CVE-2026-109618、CVE-2026-109619)基本的檢查和修復
CVE-2026-109618:可能因記憶體不足(OOM)導致記憶體損毀並執行惡意程式。CVE-2026-109619:PHP Worker 狀態未正確釋放,後續請求可能利用殘留狀態執行惡意程式。
關閉非必要的 Upload Progress 功能。
限制檔案上傳大小與 Request 大小。
調整 PHP-FPM Worker 回收機制(pm.max_requests)。
增加 PHP-FPM 狀態監控與異常自動重啟機制。
Python 安全檢查腳本
#!/usr/bin/env python3
import subprocess
import re
import sys
# 定義安全版本區間 (此版以上已修補完成)
PATCHED_VERSIONS = {
8.2: (8, 2, 35),
8.3: (8, 3, 36),
8.4: (8, 4, 27),
8.5: (8, 5, 12)
}
def get_php_version():
try:
output = subprocess.check_output(["php", "-v"], stderr=subprocess.STDOUT).decode("utf-8")
# 匹配類似 "PHP 8.3.12 (cli)" 的字串
match = re.search(r"PHP\s+(\d+)\.(\d+)\.(\d+)", output)
if match:
major, minor, patch = map(int, match.groups())
return (major, minor, patch), f"{major}.{minor}.{patch}"
except FileNotFoundError:
print("[❌] 錯誤:此系統上找不到 'php' 指令,請確認 PHP 是否已安裝於環境變數中。")
sys.exit(1)
return None, "未知"
def get_php_ini_config(setting_name):
try:
output = subprocess.check_output(["php", "-r", f"echo ini_get('{setting_name}');"], stderr=subprocess.DEVNULL).decode("utf-8").strip()
return output
except Exception:
return "無法取得"
def check_vulnerability():
print("=" * 60)
print(" PHP2Shell (CVE-2026-109618 / CVE-2026-109619) 環境安全檢查工具")
print("=" * 60)
# 1. 檢查版本
ver_tuple, ver_str = get_php_version()
print(f"[*] 偵測到本機 PHP 版本: {ver_str}")
is_vulnerable_version = False
if ver_tuple:
major, minor, patch = ver_tuple
branch = float(f"{major}.{minor}")
if branch < 8.2:
print(f"[🚨] 警告:PHP {branch} 屬於官方終止維護(EOL)版本,目前無官方安全補丁,屬於高風險漏洞範圍!")
is_vulnerable_version = True
elif branch in PATCHED_VERSIONS:
patched = PATCHED_VERSIONS[branch]
if (major, minor, patch) < patched:
print(f"[🚨] 警告:您的版本小於安全版本 ({patched[0]}.{patched[1]}.{patched[2]}),存在漏洞風險!")
is_vulnerable_version = True
else:
print(f"[✅] 安全:您的 PHP 版本已修補 ({ver_str} >= {patched[0]}.{patched[1]}.{patched[2]})。")
else:
print("[⚠️] 無法辨識的 PHP 分支,請手動核對官方安全公告。")
is_vulnerable_version = True
print("-" * 60)
# 2. 檢查配置緩解措施
upload_progress = get_php_ini_config("session.upload_progress.enabled")
# ini_get 回傳 '1' 代表 On, '' 或 '0' 代表 Off
if upload_progress in ["1", "On", "on"]:
print("[🚨] 警報:'session.upload_progress.enabled' 目前為 [開啟(On)] 狀態!")
print(" 這會讓攻擊者有機可乘,請立刻在 php.ini 中將其設為 Off。")
else:
print("[🛡️] 緩解措施已啟用:'session.upload_progress.enabled' 目前為 [關閉(Off)]。")
print("-" * 60)
# 3. 檢查系統命令函式禁用狀況
disabled_functions_str = get_php_ini_config("disable_functions")
disabled_list = [f.strip() for f in disabled_functions_str.split(",") if f.strip()]
critical_functions = ["exec", "shell_exec", "system", "passthru"]
missing_blocks = [f for f in critical_functions if f not in disabled_list]
if missing_blocks:
print(f"[⚠️] 建議:以下高危險命令執行函式「尚未」被禁用: {', '.join(missing_blocks)}")
print(" 建議在 php.ini 的 disable_functions 補上,阻斷 Webshell 命令執行管道。")
else:
print("[✅] 安全:關鍵系統命令函式 (exec, shell_exec 等) 皆已禁用。")
print("=" * 60)
# 最終診斷結論
if is_vulnerable_version and upload_progress in ["1", "On", "on"]:
print("\n[🔴 嚴重結論]:您的主機目前處於高危險曝險狀態!請立即依循指示關閉設定或升級 PHP。")
elif is_vulnerable_version:
print("\n[🟡 中度結論]:您的 PHP 版本存在漏洞,但已透過關閉 upload_progress 降低了被隨機大規模掃描直接打穿的機會。")
print(" 請注意:近期部分報告指出,單改設定非 100% 免疫,仍應儘速升級 PHP 核心。")
else:
print("\n[🟢 安全結論]:本機環境配置與版本檢測正常,無明顯 PHP2Shell 曝險跡象。")
print("=" * 60)
if __name__ == "__main__":
check_vulnerability()