# 惡意程式分析 Cheatsheet
:::info
多多利用command+f or Ctrl+f
:::
## Tool
### 靜態
* IDA Pro
* 插件
* [LazyIDA](https://github.com/L4ys/LazyIDA)
* [mkyara](https://github.com/fox-it/mkYARA)
* [go-parser](https://github.com/0xjiayu/go_parser) go語言讚讚
* [keypatch](https://github.com/keystone-engine/keypatch)
* [capa-explore](https://github.com/mandiant/capa/tree/master/capa/ida/plugin)
* Detect It Easy
* String
* TS
* Base Address
* Hex
* Import, Export
* PE Bear
* 看EXE架構
* 看overlay好用
* PE Studio
* 可以看一些混淆或是加殼
* 好像沒比DIE好用
* CAPA
* 強化版的yara
* 可以幫助看一些執行流程或是可能使用的加密法之類的
```shell=
capa target.exe
capa target.dll
# for shellcode
capa -f sc32 shellcode32.bin
capa -f sc64 shellcode64.bin
```
* Dnspy
* For .NET
* .NET的程式在IDA會甚麼都看不到,所以請使用此工具
## 動態
* x64dbg
* Breakpoint
* Debugger
* Memory
* Scylla Hide
* API Monitor
* 大招,完全沒頭緒的時候可用,似乎比較容易被病毒偵測到
* 迷之音: 左邊不要全部打勾,會很亂(但完全沒頭緒的時候還是可以勾一下)
* gdb
* For ELF
* Breakpoint
* Debugger
* Memory
## 分析方法相關
- DIE看TS, Strings 初始位置等
- IDA拆架構 <==> x64dbg跑起來
- Monitor看行為(Network, Process, Memory)
- capa快速看重點
- SandBox快速看行為(分析價值好用)
- VT
- Triage
- 公開沙箱(會外流病毒,TLP Green以上不可使用)
- DLL
- 靜態
- Export Function
- Dll Main
- 檔名,可能使用Dll Side load帶起
- rundll32: 跑dll的export function好用
- x64: C:\Windows\System32\rundll32.exe target.dll, #export functioon
- x32: C:\Windows\SysWow64\rundll32.exe target.dll, #export functioon
- DllLoader.exe: x64自帶,若沒有export function可用,但有時候會壞掉
- x64dbg
- Breakpoint
- Dll Entry Point
- LoadLibraryA
- LoadLibraryW
## Windows API相關
[msdn](https://learn.microsoft.com/zh-tw/windows/win32/api/)
### File Control
* CreateFileW
```c=
HANDLE CreateFileW(
[in] LPCWSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);
```
* CreateFileA
* 拿File Handle或是確認檔案是否存在之類的
```c=
HANDLE CreateFileA(
[in] LPCSTR 檔案名稱(應該會有完整路徑),
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);
```
* GetModuleFileNameA
* 擷取包含指定模組之檔案的完整路徑。 模組必須由目前的進程載入
* 若hModule值為0,會獲得當前process的執行檔路徑
```c=
DWORD GetModuleFileNameA(
[in, optional] HMODULE hModule,
[out] LPSTR 輸出的檔案路徑,
[in] DWORD nSize
);
```
* ReadFile
* 把fileHandle內容讀到記憶體中(FileHandle不一定會是檔案)
* stdin, stdout
* 基本上就是去看2跟3參數
```c=
BOOL ReadFile(
[in] HANDLE hFile,
[out] LPVOID lpBuffer,
[in] DWORD nNumberOfBytesToRead,
[out, optional] LPDWORD lpNumberOfBytesRead,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
```
* WriteFile
* 把記憶體的東西放到FileHandle中(FileHandle不一定是檔案)
* Stdin, Stdout, Stderror
```c=
BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
```
### Memory
* VirtualProtect
* 可以用來更改某記憶體位置的權限(0x40:PAGE_EXECUTE_READWRITE=可讀可寫可執行)
* 注意flNewProtect: 0x20 0x40
* 可能被用來動態load某個程式或dll
* 利用Scylla -> file --> Dump memory去取得load進來的程式
```c=
BOOL VirtualProtect(
[in] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flNewProtect,
[out] PDWORD lpflOldProtect
);
```
* VirtualAlloc
* 新建一塊記憶體,有時候用來執行shellcode
* 要注意flprotect為20或40的狀態
* 0x20: Read and Exec
* 0x40: Read, Write, Exec
```c=
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);
```
* VirtualAllocEx
* 相較VirtualAlloc多了Proccess Handle
* 可以在其他的Process中建立一塊記憶體
```c=
LPVOID VirtualAllocEx(
[in] HANDLE hProcess,
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);
```
* WriteProcessMemory
* 可以用來寫其他Process的Memory(同常要高權限)
```c=
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
```
### Anti-Debug
* CheckRemoteDebuggerPresent
* 就是check是否被調適
* 繞過方式直接patch參數的值即可
```c=
BOOL CheckRemoteDebuggerPresent(
[in] HANDLE hProcess,
[in, out] PBOOL pbDebuggerPresent
);
```
* IsDebuggerPresent
### 連線行為相關
### socket系列
* socket
* Create Socket
* 通訊端函式會建立系結至特定傳輸服務提供者的通訊端。
```c=
SOCKET WSAAPI socket(
[in] int af,
[in] int type,
[in] int protocol
);
```
* bind
```c=
int WSAAPI bind(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
```
* connect
```c=
int WSAAPI connect(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
```
* send
```c=
int WSAAPI send(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags
);
```
* recv
```c=
int WSAAPI recv(
[in] SOCKET s,
[out] char *buf,
[in] int len,
[in] int flags
);
```
### winhttp系列(wininet.dll)
* Internetopenw
* Create一個internet handler,讓之後的連線行為可以使用
```c=
HINTERNET InternetOpenW(
[in] LPCWSTR lpszAgent,
[in] DWORD dwAccessType,
[in] LPCWSTR lpszProxy,
[in] LPCWSTR lpszProxyBypass,
[in] DWORD dwFlags
);
```
* InternetConnectW
* 連線行為,裡面會帶IP跟Port的資訊
```c=
HINTERNET InternetConnectW(
[in] HINTERNET hInternet,
[in] LPCWSTR lpszServerName,
[in] INTERNET_PORT nServerPort,
[in] LPCWSTR lpszUserName,
[in] LPCWSTR lpszPassword,
[in] DWORD dwService,
[in] DWORD dwFlags,
[in] DWORD_PTR dwContext
);
```
* HttpOpenRequestW
* Init一個Request準備送出
* HttpOpenRequest 函数创建新的 HTTP 请求句柄,并将指定的参数存储在该句柄中。 HTTP 请求句柄保存要发送到 HTTP 服务器的请求,并包含要作为请求的一部分发送的所有 RFC822/MIME/HTTP 标头。
```c=
HINTERNET HttpOpenRequestW(
[in] HINTERNET hConnect,
[in] LPCWSTR lpszVerb,
[in] LPCWSTR lpszObjectName,
[in] LPCWSTR lpszVersion,
[in] LPCWSTR lpszReferrer,
[in] LPCWSTR *lplpszAcceptTypes,
[in] DWORD dwFlags,
[in] DWORD_PTR dwContext
);
```
* HttpSendRequestw
* 根據HttpOpenRequest所傳回的控制碼去送封包
```c=
BOOL HttpSendRequestW(
[in] HINTERNET hRequest,
[in] LPCWSTR lpszHeaders,
[in] DWORD dwHeadersLength,
[in] LPVOID lpOptional,
[in] DWORD dwOptionalLength
);
```
* InternetReadFile
* 從HttpOpenRequest之類的控制碼拿資料存到記憶體中
* 基本上去對第二個參數
```c=
BOOL InternetReadFile(
[in] HINTERNET hFile,
[out] LPVOID lpBuffer,
[in] DWORD dwNumberOfBytesToRead,
[out] LPDWORD lpdwNumberOfBytesRead
);
```
### 提權
-
### Process相關
* CreateProcessw
* 比較基本的CreateProcess方式
```c=
BOOL CreateProcessW(
[in, optional] LPCWSTR lpApplicationName,
[in, out, optional] LPWSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCWSTR lpCurrentDirectory,
[in] LPSTARTUPINFOW lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
```
* CreateProcessInternalw
* 較為底層的CreateProcess方法
* 若程式有開process但hook不到在使用
* CreateThread
* 創建Thread,起始位址會在地三個參數中
```c=
HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] __drv_aliasesMem LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out, optional] LPDWORD lpThreadId
);
```
* SuspendThread
* 暫停一個Thread的執行,某些Process Inject會使用
```c=
DWORD SuspendThread(
[in] HANDLE hThread
);
```
* ResumeThread
* 恢復Thread執行,某些Process Inject會使用
```c=
DWORD ResumeThread(
[in] HANDLE hThread
);
```
## 程式執行方法相關
## VBS
### 網路流量
* MSXML2.ServerXMLHTTP
* Open: 建立連線 (HTTP method,url,)
* SetRequestHeader: 自訂HEADER
### File相關
* Scripting.FileSystemObject
```
BuildPath 將名稱附加至現有的路徑。
CopyFile 將一或多個檔案從一個位置複製到另一個位置。
CopyFolder 將一或多個資料夾從一個位置複製到另一個位置。
CreateFolder 建立新資料夾。
CreateTextFile 建立文字檔並傳回可用來讀取、寫入至檔案的 TextStream 物件。
DeleteFile 刪除一或多個指定的檔案。
DeleteFolder 刪除一或多個指定的資料夾。
DriveExists 檢查指定的磁碟機是否存在。
FileExists 檢查指定的檔案是否存在。
FolderExists 檢查指定的資料夾是否存在。
GetAbsolutePathName 傳回指定路徑的磁碟機根目錄的完整路徑。
GetBaseName 傳回指定檔案或資料夾的基底名稱。
GetDrive 傳回對應至指定路徑中磁碟機的磁碟機物件。
GetDriveName 傳回指定路徑的磁碟機名稱。
GetExtensionName 傳回指定路徑中最後一個元件的檔案副檔名名稱。
GetFile 傳回指定路徑的檔案物件。
GetFileName 傳回指定路徑中最後一個元件的檔案名稱或資料夾名稱。
GetFolder 傳回指定路徑的資料夾物件。
GetParentFolderName 傳回指定路徑中最後一個元件的上層資料夾名稱。
GetSpecialFolder 傳回部分視窗特殊資料夾的路徑。
GetTempName 傳回隨機產生的暫存檔案或資料夾。
Move 將指定的檔案或資料夾從一個位置移至到另一個位置。
MoveFile 將一或多個檔案從一個位置移至另一個位置。
MoveFolder 將一或多個資料夾從一個位置移至另一個位置。
OpenAsTextStream 開啟指定的檔案,並傳回可用來讀取、寫入或附加至檔案的 TextStream 物件。
OpenTextFile 開啟指定的檔案並傳回可用於存取檔案的 TextStream 物件。
WriteLine 將指定的字串和新行字元寫入 TextStream 檔案。
```
* ADODB.Stream
### Shell相關
* Shell.Application
*
### VBS Debug 讚讚好用
* Print something
```vbs=
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set stderr = fso.GetStandardStream (2)
stdout.WriteLine "Hello World"
```
* Chr
* 跟Python的chr很像,就是把ascii code轉成文字
* CLng
* 強制轉換,把東西轉成log int的形式
## Powershell 執行
* Print something
* 若出現& iex可使用& write-output把解密後的payload輸出
* Set-ExecutionPolicy RemoteSigned
* 可以跑沒被簽名的ps1
## 常見的惡意程式手法
### 酷酷的Dll Hijacking
* 最常見: Dll sideload,優先把同一個目錄底下的dll load進去
* Dll Injection
* https://ithelp.ithome.com.tw/articles/10188468
* 首先用 CreateProcess 建立一個Process,並設置該程序的狀態為 Suspended
* 接著執行 VirtualAllocEx,分配一塊記憶體空間給剛建立出來的程序。
* 呼叫 WriteProcessMemory,把要 Inject 的 DLL 路徑名稱寫入到上述步驟分配出來的空間。
* 使用 CreateRemoteThread 建立一條 Thread,讓 Thread 利用 LoadLibrary funtion 載入要用到的 DLL。該 DLL 的路徑名稱位於第二步驟從記憶體切割出來的空間裡。基本上到這一步驟,已經算是成功地把 DLL inject 到程序裡。
### 酷酷的DLL Hollowing
* 基本上思路就是在process執行期間塞入一個合法的DLL,之後把DLL挖空,並塞入惡意的程式碼片段,與process hollowing概念差不多
* 流程
* 先在目標process中塞入一個系統合法DLL
* VirtualAllocEx --> Alloc一塊記憶體空間
* WriteProcessMemory --> 把該DLL寫入alloc的空間
* CreateRemoteThread --> 把remote process暫停執行
* 找到該DLL的Base Address
* EnumProcessModules, GetModuleBaseNameA --> 找目標DLL的名稱
* ReadProcessMemory --> 找DLL Base Address
* 塞Shellcode並執行
* WriteProcessMemory --> 就寫入Shellcode
* CreateRemoteThread --> 執行
### Office Template Injection
* 一種注入手法,攻擊者可透過此手法把遠端含有惡意巨集的office檔案在使用者打開被注入的office檔案後下載下來並執行
* 手法基本上是去改word解壓縮後裡面會有 `word/_rels/setting.xml`的東東

## Process Injection
* Process Hollowing
* https://attack.mitre.org/techniques/T1055/012/
* 顧名思義,就是把一個Process的執行section(.text)搬空,然後用惡意的.text段去做替換,目的是用來偽裝成其他合法的process讓使用
## 跑 Shellcode
* https://github.com/OALabs/BlobRunner
* 可用來跑SMC自解的payload,會利用createthread的方式去跑,在x64把斷點設在createthread的起始位址即可(第三個para)
## 好用的工具
* Cobaltstrike Scan
* YARA: https://github.com/avast/ioc/blob/master/CobaltStrike/yara_rules/cs_rules.yar
* 掃Memory Beacon: https://github.com/Apr4h/CobaltStrikeScan
* 解CobaltStrike config
* Beacon
* https://github.com/Sentinel-One/CobaltStrikeParser
* Stager
* https://github.com/stairwell-inc/cobalt-strike-stager-parser/
* Beacon in memory
* https://github.com/k3idii/CobaltStrike-Tools
* Python xor file
```python=
import sys
# Read two files as byte arrays
file1_b = bytearray(open(sys.argv[1], 'rb').read())
file2_b = bytearray(open(sys.argv[2], 'rb').read())
size = len(file1_b) if len(file1_b) < len(file2_b) else len(file2_b)
xord_byte_array = bytearray(size)
for i in range(size):
xord_byte_array[i] = file1_b[i] ^ file2_b[i]
open(sys.argv[3], 'wb').write(xord_byte_array)
print "[*] %s XOR %s\n[*] Saved to \033[1;33m%s\033[1;m."%(sys.argv[1], sys.argv[2], sys.argv[3])
```
## IDA Script
```c=
static main()
{
auto i,fp;
fp = fopen("./dump","wb");
auto size = 0x1fe00;
auto start = 0x1001A760;
for(i=start;i<start+size;i++){
fputc(Byte(i),fp);
}
fp.close();
}
```
## 開源Backdoor
* [Geacon](https://github.com/darkr4y/geacon)
* [TinySHell](https://github.com/creaktive/tsh)
* [TinySHell Go Lang version](https://github.com/CykuTW/tsh-go)
* [Sliver](https://github.com/BishopFox/sliver)
https://securelist.com/applied-yara-training-qa/104007/
https://gist.github.com/Neo23x0/e3d4e316d7441d9143c7