繼續補坑…
ref: https://www.youtube.com/watch?v=gI0nZR4z7_M
ubuntu 可以直接用 snap 裝 ghidra
sudo snap install ghidra
照著影片說,第一步要先修長度
僅需打勾 PE Header Annotation
照教學說,惡意程式是把 shellcode append 在 .text 區段後面,所以這一段就是要把 .text 區段做 patch,
在這一步要做的就是把 physical address 與 virtual address 跟 size of raw data 對齊
記得要 enable editing of bytes
全選後選 extract and import
analysis options 多選 Decompiler Parameter ID
與 WindowsPE x86 Propagate External Parameters
前者是為了獲得較正確的變數名稱,後者是可以會將 function 的參數資訊以註解方式顯示
如果有看到 FUN_0051B908
那就代表 patch 成功了
Dump payload
根據動態分析(process monitor)可以得知他會寫一個 idx.ini
ok,先從 write
開始追
像這種 Library function 不看,要看的是在 User 寫的程式有 call 的
最後只有FUN_00401810
符合要求
照著教學把 function name 改成 write_somthing
這個名稱
然後透過 CreateFileW
得知 param_2
是 file_name
然後找到是誰 call write_somthing 的
然後一樣改參數名稱
也順便把能識別的 function 做命名
至於那個 0x88
到底是什麼呢? 回頭去看 write_somthing 怎麼使用這個變數的
找msdn
https://learn.microsoft.com/zh-tw/windows/win32/api/libloaderapi/nf-libloaderapi-findresourcew
從這邊可以知道 0x88 是 exe 的 Resource ID
嘗試把他解出看
但沒什麼好看的,有可能 shellcode 是動態寫入的,用靜態來看只會看到一堆 gadget
於是透過 offset 來找看看有沒有其他東西,將 Resource Address 扣除 ImageBaseAddress0x0056ec78 - 0x400000 = 0x16ec78
(ImageBaseAddress直接看程式最上面的address就有了)
第一個不看,二三個都在同一個 funtcion
首先第14行感覺是拿 module base address,所以改一下變數名稱 pHVar3
變成 module_addr_400000
然後看一下到底是誰會用他,發現到它是被包含在 __crtExitProcess
內,有可能是一個被 Modify 過的 standard lib
再回去 function 內,要如何推出其他 offset 的 function 呢?
看一下這一行,這個是透過 0x16ec78
找到的,而這個 0x16ec78
是使用 ImageBaseAddress 加上 offset 得到的
所以可以透過一樣的方法,看 asm 去推導其他的 function
看 pcVar1
,他是使過 0x11c27c
跟 ImageBaseAddress 相加得到的,把這兩個相加後去看會得到什麼0x11c27c+0x400000=0x51c27c
基本上看到查到這邊後,就直接把 FUN_0051B908
改成 shellcode
了
然後 pcVar1
也改成 VirtualAlloc
,順道連 DataType 一起改 (右鍵->Retype Variable)0x40
的部分改成 PAGE_EXECUTE_READWRITE
,0x1000
的部分改成 MEM_COMMIT
(右鍵-> Set Equate..)
需要的話可以再加註解 (右鍵->Comments)
全部大概長這樣
繼續追下去,這次要看,程式拿這個 VirtualAlloc 的 Buffer 要幹什麼事情
進去 FUN_0051B802
,看到這個感覺就很像是 decode function
看完 decode function 之後回來 shellcode,需要知道 decode 之後他的 entry point 在哪
首先第42行,將 Resource Buffer 的內容複製進 VirtualAlloc buffer 內,後面就是做 count,在47行對 VirtualAlloc Buffer 做 decode 之後,48行就是 shellcode 的 entry point,0xfab 是 entry 的 offset
照教學的做法是直接將 asm 轉 C 然後編譯程式後直接利用他 decode,但…這一塊要處理很多 exception 很麻煩,我覺得更快的方法還是直接做動態分析把 shellcode 拉出來(我們已經知道 shellcode會存放在哪了)
首先因為系統會有 ASLR,所以要先知道 Ghidra 與 Windbg 的 ImageBaseAddress 的 offset 多少
透過 u $exentry
取得 entry point address,透過圖中方法可以找到 MZ header,其實透過 !peb
也可以
然後把 Windbg 的 base address 扣掉 ghidra 的 0x400000 就取得 offset 了0x10f0000-0x400000=0xcf0000
然後下斷點在 0x51b9b8+0xcf0000=0x120b9b8
,然後看一下 register
就可以知道解完的 shellcode 在 0xcb0000
,0xcb0fab
是 entry point
然後順勢使用 .writemem [file path] 0xcb0000 L?[mem range]
,這邊我直接碰到底端,就直接全 dump
Analysis Payload
接著來看 decode 後的 shellcode 長怎樣
首先在 0xfb6
看到針對 FS:0x18 做事情
這邊改一下 DATA TYPE
相關需要的可以在這下載
https://github.com/0x6d696368/ghidra-data/tree/master/typeinfo
http://terminus.rewolf.pl/terminus/
Change unaff_FS_OFFSET
to NT_TIB*
Change Self to TEB*
Change p_Var2
to LDR_DATA_ENTRY
Create a new structure LDR_DATA_TABLE_ENTRY_0x10
首先複製要更改的 struct 其他地方
Change local_64
to LDR_DATA_TABLE_ENTRY*
從 22 跟 23 行可以看出他針對 Kernel32.dll
做 dllname 的遍例尋找
Import Table Hash
接下來看 FUN_00000010
,但這邊不曉得是不是因為我是直接動態 leak 出來的,怎麼樣都解不出教學的樣子,索性直接貼成果
下一步,嘗試 leak function hash list
把 FUN_00000010
拿來改一下
改完後的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv)
{
char cVar1;
char *name;
int iVar2;
char *pcVar3;
int local_c;
int local_8;
local_8 = 0;
local_c = 0;
pcVar3 = name = argv[1];
cVar1 = *pcVar3;
while (cVar1 != '\0') {
local_c = local_c * 0x21 + (int)cVar1;
pcVar3 = pcVar3 + 1;
cVar1 = *pcVar3;
}
printf("%s: %x\n", name, local_c);
//} while (local_8 < *(int *)(iVar2 + 0x18));
return 0;
}
然後 clone https://github.com/0x6d696368/ghidra-data.git
cat * | grep -Eo NAME=.+\" | awk -F \" {'print $2'} | grep -v .dll > functionNames
這樣就有 function hash list 了
然後看一下 shellcode 找的 function 是那些
然後繼續修 function type …
先創一個 structure
照著 hash table 一個一個壓上去
接著回到 entry 看最後一個 function,FUN_00000950
發現他有用到 EAX 的 register,看一下 EAX 誰會用到
編輯一下 FUN_00000950
,幫他加個參數
接著看 FUN_000002e1
idx.txt
c2
conclusion
- 透過
GetAdaptersInfo
取得 MAC 資訊 - 透過
MD5Init, MD5Update 和 MD5Final
計算 MAC 的 MD5 值 - 當 Match 到 MD5 的值時,從
asushotfix[.]com
下載 shellcode 並執行 - 如果沒 Match 的話, write something to idx.txt