PHP 提供強大的系統層互動能力,但若配置不當或程式碼未嚴格驗證輸入,部分函數可能成為攻擊者植入 Web Shell、執行任意指令、竊取伺服器資訊的關鍵跳板。本文系統整理 25 個高風險函數,依功能分類並標註危險等級,提供防禦策略參考。
一、命令執行類(最高風險)
允許直接呼叫作業系統 Shell 指令,是駭客獲取伺服器控制權的主要途徑。
| 函數 | 功能 | 風險 | 攻擊案例 |
exec() | 執行外部程式,回傳最後一行輸出 | 高 | exec("rm -rf /")、exec("cat /etc/passwd") |
system() | 執行外部程式並直接輸出 | 高 | 同 exec(),但輸出直接顯示於頁面 |
passthru() | 執行外部程式並原始輸出(二進位安全) | 高 | 常用於圖片處理指令注入 |
shell_exec() | 透過 Shell 執行指令,回傳完整輸出字串 | 高 | 反引號 `cmd` 的函數別名 |
proc_open() | 執行指令並開啟檔案指標進行讀寫 | 高 | 雙向通訊,可建立互動式 Shell |
proc_get_status() | 取得 proc_open() 開啟進程資訊 | 高 | 輔助進程控制與偵測 |
popen() | 開啟指令管道讀寫 | 高 | 單向管道,可讀取指令輸出 |
pcntl_exec() | 在當前進程空間執行指定程式 | 高 | 需 pcntl 擴充套件,可繞過 disable_functions |
二、環境與配置操作類
| 函數 | 功能 | 風險 | 說明 |
ini_set() / ini_alter() | 執行期修改 PHP 設定 | 高 | 可關閉 safe_mode、開啟 allow_url_include 等 |
ini_restore() | 恢復 PHP 設定初始值 | 高 | 可撤銷防護設定 |
dl() | 動態載入 PHP 擴充套件 | 高 | 可載入惡意 .so/.dll,PHP 7+ 已移除 |
putenv() | 設定環境變數 | 高 | 舊版可配合 sendmail 執行指令(CVE-2016-10033) |
chroot() | 改變進程根目錄 | 高 | 需 CLI 模式、非 Windows,可逃逸容器 |
三、檔案系統與權限操作類
| 函數 | 功能 | 風險 | 說明 |
chown() | 改變檔案擁有者 | 高 | 需 root 權限,可竊取敏感檔案 |
chgrp() | 改變檔案群組 | 高 | 同上 |
symlink() | 建立符號連結 | 高 | 可建立連結至敏感檔案(如 /etc/passwd)再透過 Web 讀取 |
readlink() | 讀取符號連結目標 | 中 | 資訊洩露風險 |
scandir() | 列出目錄內容 | 中 | 目錄遍歷攻擊前置偵察 |
四、網路與通訊類
| 函數 | 功能 | 風險 | 說明 |
fsockopen() / pfsockopen() | 建立 Socket 連線 | 高 | 可發起 SSRF 攻擊、連接內部服務、反彈 Shell |
stream_socket_server() | 建立 Socket 伺服器 | 中 | 可監聽埠口,配合反彈 Shell 使用 |
syslog() | 發送訊息至系統日誌 | 中 | 日誌注入、資訊洩露 |
五、資訊洩露與除錯類
| 函數 | 功能 | 風險 | 說明 |
phpinfo() | 輸出完整 PHP 環境資訊 | 中 | 洩露版本、模組、路徑、環境變數等敏感資訊 |
error_log() | 發送錯誤訊息至指定位置 | 低 | 舊版可繞過 safe_mode 執行指令 |
六、CLI SAPI 相關風險
若編譯 PHP 時啟用 --enable-cli,產生的 php 執行檔可能被攻擊者上傳並透過排程任務、上傳腳本等方式執行,建立持久化後門。生產環境 Web 伺服器不應安裝 CLI 版本,或以 disable_functions 封鎖高危函數。
防護建議:php.ini 關鍵設定
; 1. 封鎖高危函數(依實際需求調整)
disable_functions = exec,system,passthru,shell_exec,proc_open,proc_get_status,popen,pcntl_exec,dl,ini_set,ini_alter,ini_restore,putenv,chroot,chown,chgrp,symlink,fsockopen,pfsockopen,stream_socket_server
; 2. 限制目錄存取
open_basedir = /var/www/html:/tmp:/var/tmp
; 3. 關閉危險設定
allow_url_fopen = Off
allow_url_include = Off
expose_php = Off
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
; 4. Session 安全
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
程式碼層面防禦原則
- 絕不信任使用者輸入:所有傳入系統指令的參數必須經過
escapeshellarg()、escapeshellcmd() 處理,並採用白名單驗證。
- 最小權限原則:Web 進程以低權限帳號運行(如
www-data),禁止 root 執行 PHP-FPM。
- 停用不必要的擴充套件:移除
pcntl、posix 等非必要模組。
- 部署 WAF/RASP:即時偵測指令注入、異常檔案存取等行為。
- 定期審計:掃描專案中是否直接使用高危函數,重構為安全替代方案(如
Symfony Process、Guzzle 等)。
總結
PHP 危險函數並非「不能用」,而是「必須受控」。理解各函數的攻擊面、配合 disable_functions、open_basedir、權限隔離與程式碼審計,才能在保留功能彈性的同時,將風險降至最低。現代框架(Laravel、Symfony)已封裝安全的檔案、程序、網路操作元件,建議優先使用框架提供的抽象層而非直接呼叫原生函數。