WordPress

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()