PowerShell是微軟為Windows平臺制作的新一代命令行操作環境。和傳統的命令行環境相比,PowerShell的功能更加強大,使用方式也非常靈活。但這些新特性給用戶和系統運維人員帶來便捷的同時,也存在很大的安全風險。美國賽門鐵克公司發布的一份報告指出,該公司在2016年分析的49127個PowerShell腳本樣本中,有95. 4%的樣本是惡意的。騰訊公司發布的2019年度企業安全報告也指出,在被惡意利用的系統組件中,利用PowerShell組件實現遠程下載占比達90%。敵對勢力在近年來對我國發起的網絡攻擊中,PowerShell惡意腳本也成為經常使用的攻擊手段之一。本文將在介紹PowerShell的功能特點和安全機制的基礎上,概述部分安全機制繞過方法,并提出針對PowerShell攻擊的檢測和防御方法。
一、PowerShell簡介
從Windows 95正式脫離DOS系統、成為可獨立運行的操作系統到現在,微軟在各版Windows系統中都保留了命令行窗口,即“命令提示符”,用于兼容DOS程序、便于用戶執行命令操作。隨著技術的演進,功能有限的“命令提示符”已經不能滿足運維需求。為此,微軟于2006年發布了新一代命令行環境,即PowerShell1.0。從Windows7和Windows Server2008 R2開始,微軟正式將PowerShell集成到系統中,便于管理員進行系統管理。在2016年,微軟將PowerShell開源,并提供了跨平臺支持,使用戶在Linux等系統中也可以使用PowerShell的部分功能。
PowerShell基于.Net架構研制,既兼容原“命令提示符”的所有功能,又吸收了Linux系統中Bash命令行的諸多優點。PowerShell的主要特性有:一是具備強大的系統管理功能,不僅可以直接操作注冊表,還可以通過WMI(WindowsManagement Instrumentation)接口對操作系統進行各類配置;二是支持管道操作,即前一條命令的返回結果可直接作為后一條命令的參數,因此可以通過管道將多條命令組合成一條命令,而且可以通過查詢、篩選等命令對經過管道傳輸的數據進行過濾;三是支持網絡和遠程處理,除下載和傳輸文件等常規網絡操作之外,還支持通過遠程管理的方式在一組網絡可達的計算機中執行PowerShell命令或腳本。此外,PowerShell還支持對象操作、后臺異步運行等特性。
PowerShell最大的優勢是支持腳本解析運行和調試,而且腳本編寫方式非常靈活。在腳本文件中,除PowerShell的內置命令外,還可以直接調用.Ne t框架的類庫實現非常復雜的程序邏輯。PowerShell腳本文件的正文一般為純文本形式,語法規則與其他腳本語言類似,常用的擴展名為ps1、psc1和psm1,分別表示通用腳本、命令行腳本和腳本模塊。可以根據上述特征初步判斷一個文件是否為PowerShell腳本文件。
二、 PowerShell安全機制
PowerShell強大的功能在給運維人員和用戶帶來方便的同時,也給攻擊者帶來了可乘之機。從上節介紹的PowerShell特性可以看出,攻擊者一旦能夠從遠程執行PowerShell腳本,或誘使用戶執行惡意的PowerShell腳本,就可能執行非常危險的操作,例如修改系統安全配置、竊取用戶數據文件等,甚至可以進一步植入后門進行持續性攻擊。為了降低可能存在的安全風險,微軟為PowerShell提供了一些基本安全機制,限制惡意腳本的直接運行。最常見的安全機制有“執行策略” 和反惡意程序掃描接口(Anti-Malware ScanInterface,AMSI)。
“執行策略”主要通過檢測和驗證簽名的方法限制腳本文件的運行,該策略的默認取值為Restricted,即除了部分帶有微軟數字簽名的腳本文件外,其他腳本一律無法直接運行。此外常見的取值還有:AllSigned,即經數字簽名后的腳本才可運行;RemoteSigned,即本地腳本可直接運行,遠程腳本則需數字簽名才能運行;Unrestricted,即所有腳本文件均可運行。用戶可以在PowerShell命令行中運行Get-ExecutionPolicy命令查看當前的策略取值。
AMSI用于為Microsoft Defender等殺毒軟件提供PowerShell腳本檢測接口。腳本在運行時,AMSI將對腳本的代碼進行檢測,并通過接口傳遞給系統內的殺毒軟件。如殺毒軟件發現代碼存在惡意特征,將中止腳本的執行,并將結果反饋給用戶。
除了以上2種安全機制外,PowerShell還能夠對可運行的語言和函數進行限制,這些機制都可以在一定程度上提高PowerShell運行環境的安全性。
三、PowerShell攻擊方法
利用PowerShell進行攻擊一般分為2個方面:一方面是攻擊者利用系統漏洞向用戶終端釋放惡意的PowerShell腳本,另一方面是攻擊者通過發送釣魚郵件等方式誘導用戶下載和運行惡意PowerShell腳本。盡管PowerShell提供了相應的安全機制,但是攻擊者依然可以通過多種方法繞過這些機制進行攻擊。針對“執行策略”對運行腳本文件的限制,攻擊者可誘導用戶關閉這一限制,或通過參數設置等方法繞過該限制,而由于腳本文件大多為純文本形式,攻擊者可以很容易地對腳本的內容進行編碼、混淆,使其繞過AMSI機制的檢測,也繞過用戶肉眼的識別。
下面以輸出“Hello World”為例介紹幾種常見的繞過“執行策略”、對代碼進行編碼和混淆的方法。為了便于介紹,我們首先創建一個腳本文件,內容為“write-host'HelloWorld'”,保存在D:\test.ps1。如果用戶在該文件的圖標上點擊右鍵,選擇“使用PowerShell運行”,是可以作為主動執行的方式運行該腳本文件的。如果在PowerShell命令行中直接輸入上述內容,同樣可以運行,如圖1的①所示。但是,受“執行策略”的限制,在PowerShell命令行中無法直接運行該腳本文件,如圖1 的②所示。然而,如果通過Get-Content方法讀取文件內容,再將內容通過管道作為PowerShell的輸入,則可繞過這一限制,如圖1的③所示。
圖1 在Pow erShell中執行命令
即使用戶依然將“命令提示符”作為默認的命令行環境,也同樣可以調用PowerShell來執行腳本文件和命令。例如:(1)可以通過臨時修改“執行策略”的方式運行腳本文件;(2)可以將圖1在PowerShell中執行命令經過Base64編碼后的命令直接解碼執行;(3)可以從網絡直接下載腳本文件并執行;(4)經過內容混淆的命令依然可以執行。上述事例分別如圖2的①~④所示。
圖2 在傳統的“命令提示符”中執行Pow erShell命令
此外,PowerShell的很多安全機制需要3.0或更高的版本才能支持。然而,由于兼容性等原因,系統中可能同時存在多個版本的PowerShell。在高、低版本共存的環境下,即使默認使用的是高版本,攻擊者也可能通過命令行參數調用低版本PowerShell,發起“降級攻擊”,從而繞過某些安全機制。
需要說明的是,PowerShell腳本的執行權限和當前用戶的權限是一致的。如當前用戶具有系統管理員權限,且未通過Windows內的用戶賬戶控制(UserAccountControl,UAC)進行必要的防護,則以該用戶權限執行的PowerShell腳本就可能對系統造成非常大的危害。但是,即使當前用戶是普通用戶,通過PowerShell腳本也能夠竊取該用戶有權訪問的所有文件,包括其工作文件和私人文件等。
四、 PowerShell攻擊的檢測
從上面的介紹可以看出,PowerShell腳本文件可以通過編碼、混淆、網絡下載、轉換為命令行命令等多種方式執行。如果將這些方式復合起來,可以僅用一條命令就從網絡下載經編碼和混淆的腳本文件并在本地運行。這使得PowerShell攻擊不僅難以被發現,還可能因為不落盤存儲等原因難以被追蹤。但是,攻擊事件依然可能會在終端系統中留下一些痕跡,這為我們檢測攻擊事件提供了可能。下面介紹幾種檢測方法。
查看系統日志是最有效的檢測方法之一。Windows系統默認會記錄包括PowerShell引擎啟動事件等在內的一些基礎日志。在系統的管理工具中找到“事件查看器”的圖標,或在命令行中運行eventvwr.msc,打開“事件查看器”。然后在左側依次展開“應用程序和服務日志—Windows PowerShell”,即可查看關于PowerShell的日志,如圖3所示。
圖3 查看Pow erShell的事件日志
在系統日志中,事件ID為400的事件表示引擎啟動成功,403則表示引擎停止。用戶主動打開PowerShell命令行,命令行加載時會生成400事件。如用戶通過命令行調用PowerShell執行腳本文件,則會在腳本執行開始時生成400事件,在腳本執行完成時生成403事件。根據事件的時間,結合其他異常情況,可以對是否發生過PowerShell攻擊做出一定的判斷。此外,其他類型的事件日志也可以提供相應的輔助參考。
系統默認記錄的PowerShell事件類型是有限的,可通過修改系統策略的方法補充其他需記錄的事件類型。具體方法是:首先在系統的管理工具中找到“編輯組策略”的圖標,或在命令行中運行gpedit.msc,打開“組策略編輯器”;然后依次展開“本地計算機策略—計算機配置—管理模板—Windows組件—WindowsPowerShell”,在右側選擇“啟用模塊日志記錄”,設置為“已啟用” ,并根據需要將相應模塊名稱添加到列表中,如“Microsoft.PowerShell.* ”等;最后再在右側選擇“打開PowerShell腳本塊日志記錄”,設置為“已啟用”,并勾選下方的“記錄腳本塊調用啟動/停止日志”。這些操作將進一步豐富PowerShell日志的內容,為分析后續可能發生的攻擊事件提供支持。
除了系統日志外,PowerShell攻擊還可能留下其他一些蛛絲馬跡。例如,有的PowerShell攻擊腳本需周期性執行,或在終端開機時自動運行,那么系統的計劃任務列表和啟動項中可能會保留有相應的記錄,可通過相應的管理工具或微軟提供的autoruns等工具進行檢查。
此外,對于一些落盤存儲和執行的PowerShell腳本,攻擊者為確保攻擊成功,通常會使用絕對路徑。因此,一些權限較低的目錄很可能成為惡意腳本文件臨時存儲的地方,特別是用戶的數據目錄(如C:\Users\用戶名\AppData下的各個子目錄)等。可以檢查相應目錄中是否存在異常的腳本文件,特別是以ps1、psc1和psm1等為擴展名的PowerShell腳本文件。必要時,還可以通過數據恢復工具檢查相關目錄中是否存在被刪除的腳本文件。
五、針對PowerShell攻擊的防御方法
在Windows 7及更高版本的系統中,PowerShell是內置組件,無法直接卸載。為了降低PowerShell攻擊的風險隱患,提高系統的安全性,可采取以下措施。
升級PowerShell 到更新版本。在命令行中運行“Get-Host”即可查看當前PowerShell的版本號。為使用PowerShell內置的安全特性,建議升級到5.0 以上版本。
檢查是否存在舊版本。由于PowerShell支持多版本并存,即使已安裝高版本,也應當在命令行中嘗試運行形如“PowerShell.exe -version 2 Get-Host”的命令,判斷系統中是否依然存在較低版本的PowerShell,避免“降級攻擊”。
檢查“執行策略”是否已設置為“Restricted”。如果不是,可通過“Set-ExecutionPolicy Restricted”命令進行設置。
限制PowerShell的語言模式。如僅需保留PowerShell最基本的運行環境,不需要調用.Net 框架的類庫,則可限制PowerShell支持的語言種類。具體做法是,首先在系統的環境變量中添加名為“__PSLockdownPolicy”的變量,取值為“4”;然后可以在PowerShell命令行中輸入“$ExecutionContext.SessionState.LanguageMode” 進行驗證,如返回結果由“FullLanguage” 變為“ConstrainedLanguage”,則表明語言模式修改成功。此時,大部分惡意程序都會因無法調用.Net 框架的類庫而無法正常運行,從而不會對系統造成顯著破壞。
安裝殺毒軟件并定期升級。一些殺毒軟件能夠檢測PowerShell 腳本文件的惡意特征,有的還能夠在執行PowerShell 腳本文件時發現其惡意行為,這也有助于防范惡意PowerShell 腳本的運行。
對于Windows XP系統,由于PowerShell是可選組件,如在日常工作中確實無需使用PowerShell的,還可通過控制面板中的“添加/刪除程序”功能卸載該組件。
與此同時,用戶還應提高辨別意識,養成良好的上網習慣,不訪問來路不明的網站、郵件及其附件,不運行可疑的程序和腳本文件,定期更新殺毒軟件和系統補丁,防止PowerShell惡意腳本的植入和運行。
(原載于《保密科學技術》雜志2020年2月刊)