← 回到筆記

FIELD NOTES /

Windows Malware Development:技術鏈與逆向註解

以防禦與授權研究為前提,完整拆解 staging、載入、記憶體異常、process injection、持久化、C2 與證據鏈。

#Malware#Reverse Engineering#C/C++

先把 Malware 看成一條行為鏈

只看單一 hash、domain 或 API 很容易誤判。較完整的模型是把樣本拆成多個階段,再為每一階段建立 artifact、telemetry 與假設:

Plain Text
Delivery / Staging
  → Execution / Loader
    → Discovery / Privilege Context
      → Persistence
        → Defense Evasion
          → Credential / Collection
            → Command and Control
              → Actions on Objectives

實際樣本不一定包含全部階段,也可能把不同功能拆到多個 processes、services 或 modules。分析目標不是替樣本貼一個家族名稱,而是回答:它做了什麼、在什麼條件下做、留下哪些可重現證據、我們能在哪一層阻止或偵測。

惡意程式感染向量示意
同一 campaign 可能使用多種 delivery 與 post-exploitation 技術;防禦需要跨 process、memory、file、registry 與 network 建立時間線。 — Wikimedia Commons

建立安全、可重複的分析環境

最低隔離要求

  • 專用 VM,不使用日常工作帳號與真實瀏覽器資料。
  • 分析前建立 snapshot,樣本與工具版本記錄在 case notes。
  • 預設斷網;需要觀察流量時使用模擬 DNS/HTTP 服務或嚴格受控出口。
  • 關閉 host integration、shared clipboard、shared folders 與不必要的 USB passthrough。
  • 從乾淨基線產生 file、registry、service、scheduled task 與 process 差異。
  • 所有時間來源統一,保留 timezone 與 clock drift 資訊。

證據處理

對每個樣本至少記錄:原始檔 SHA-256、取得來源、取得時間、檔案大小、簽章狀態、分析 VM build、工具版本與每次執行的命令列。原始樣本應設為唯讀保存;衍生檔、unpacked image、memory dump 與報告分開雜湊。

Triage:先決定從哪裡深入

1. 檔案與 PE 結構

面向觀察項目解讀方式
IdentityHash、size、compile metadata、signatureTimestamp 可偽造;signature 要檢查 trust chain,不只看欄位存在
PE headersMachine、subsystem、entry point、sections異常 alignment 或權限是線索,不是 verdict
ImportsStatic imports、delay imports、ordinalImport 很少可能是 packer,也可能是簡單程式
ResourcesManifest、icons、embedded config比對宣稱產品與實際 signer/version info
Entropy全檔與逐 section entropy壓縮、加密、圖片與合法 packer 都會提高 entropy
OverlayPE image 結束後的額外資料Installer、signature 與惡意 config 都可能存在 overlay

第一輪的目的不是「靜態分析就定罪」,而是產生待驗證假設。例如 .text 很小、某高 entropy section 很大、imports 只剩幾個 loader API,可能表示執行時會解包;下一步就應在 entry point、memory protection change 與新 executable region 之間建立關聯。

2. Strings 與 configuration

將 strings 分為四類比全部丟進 IOC 清單更有效:

  1. 功能字串:API、錯誤訊息、format string。
  2. 基礎設施:domain、URI pattern、user-agent、certificate metadata。
  3. 主機 artifact:mutex、pipe、service、task、registry path、file path。
  4. 編譯 artifact:PDB path、language runtime、library signature。

需要確認字串是「真的被引用」還是未使用資料。加密 blob 則先辨識 framing:版本、長度、nonce、key identifier、compression marker 與 checksum;不要一看到 XOR loop 就假定所有資料使用同一 key。

Execution 與 Loader:觀察狀態變化

Loader 的本質是把某種 representation 轉成可執行狀態。防禦者不需要複作 loader,也能從狀態轉換辨識它:

Plain Text
輸入 bytes
  → allocation / section mapping
  → copy / decompress / decrypt
  → relocation 與 import resolution
  → protection transition
  → control transfer

正常 Windows loader 會建立 image mapping、處理 imports、TLS 與 loader bookkeeping。自訂 loader 或 reflective loading 可能產生不同 footprint,例如 executable private pages、PE-like bytes 不在 module list、thread stack 回到未命名 region,或 image mapping 與 disk file 不一致。

Memory region 的五個問題

對每段可疑記憶體依序問:

  1. 它從哪裡來? Allocation、section map、image load 或 copy-on-write?
  2. 誰寫入? 本 process、另一 process、kernel component 或 debugger?
  3. Protection 如何變化? RWX、RW→RX、image-backed executable 或 guard pages?
  4. 誰執行? Existing thread、new thread、APC、callback 或 exception path?
  5. 內容像什麼? PE、shellcode-like code、JIT code、decompressed config 或純資料?

RW → RX Lab — 注入記憶體 protection 變化

RW0x000001A4`00380000VirtualAlloc(RW) — 可寫入 shellcode

PAGE_READWRITE

Step 1 / 4

Pointer Lab — 陣列索引 vs 指標偏移

索引 a = 0

Memory (each int = 4 bytes) — 點 cell 切換 a

當 a = 0 時,*(p + a) 讀到 10,位址 0x100040

int values[4] = { 10, 20, 30, 40 };
int a = 0;

values[a]     → 10
*(values + a) → 10
&values[a]    → 0x100040

API Resolution 與 Hashing:從分析角度還原

部分樣本不保留敏感 API 明文,而是在執行時走訪 export table,以 hash 或自訂比較函式選出目標。分析重點不是背某個 hash 常數,而是辨識 resolver 的輸入、正規化規則與輸出。

API Hashing 迴圈的逆向思路

hash = seed
for each byte in export_name
hash = rotate_or_mix(hash, byte)
compare hash with constant
return resolved address

先確認 seed、位元寬度與大小寫正規化。

Step 1 / 5

Resolver 還原流程

  1. 找到遍歷 export directory 的 loop。
  2. 記錄 module selection、name normalization 與 hash width。
  3. 用獨立腳本對合法 DLL exports 批次計算。
  4. 對 collision 保留所有候選,不要過早命名。
  5. 依 call-site 參數、回傳用途與動態 trace 確認函式。
  6. 將確認後的名稱回填 IDA/Ghidra,重跑 call graph 與 capability grouping。

這種方法也適用於 syscall wrappers、COM method table 與動態載入的 runtime symbols。

Process Injection:技術家族與證據鏈

MITRE ATT&CK 將 Process Injection 歸為 T1055,並拆成 DLL injection、PE injection、thread execution hijacking、APC、process hollowing 等子技術。不同實作共享的高階序列通常是:取得目標 process、把 code/data 放進其 address space、讓目標 execution context 使用它。

技術家族主要狀態變化較有價值的證據
Remote allocation + executionTarget 出現外部寫入的 private region,接著有新執行點Process access、cross-process write、thread start address、region protection
Section-based mapping同一 section 映射到兩個 processes 或 target 出現非典型 mappingSection provenance、mapped views、memory content、creator process
APC-based executionCode 經由既有 thread 的 APC path 執行APC delivery context、alertable wait、target region、preceding process access
Thread context hijack既有 thread 的 instruction context 被改變Suspend/resume、context change、stack discontinuity、new IP region
Process hollowing / tamperingProcess identity 與實際 memory image 不一致Original image、replacement mapping、PEB image base、Sysmon process tampering
DLL-based injectionTarget 載入非預期 DLLImage-load event、module path、signature、load provenance、search-order context
Virtual address space 配置
Injection 調查不只看 API:要把 target VAD、module list、thread start、process access 與 image-load timeline 串在一起。 — Microsoft Learn

為什麼單一 API rule 不夠?

Debugger、accessibility software、security products、game overlays 與管理工具都可能跨 process 開 handle、讀寫記憶體或建立 thread。反之,攻擊者可用不同 native mechanisms 達成相同狀態。因此可靠偵測應聚合:

  • Source process reputation、signer、integrity 與 parentage。
  • Granted access 與 target sensitivity。
  • Target memory region 的 type、protection 與 provenance。
  • Execution 是否落在合法 loaded image。
  • 前後是否伴隨 credential access、persistence 或 network beacon。

Persistence:看「自動啟動關係」而不是只背位置

Persistence 的共同目標是建立「某個 trigger 發生時,自動啟動攻擊者控制內容」的關係。可依 trigger 分類:

Trigger例子調查重點
User logonRun keys、Startup items、logon scriptsOwner SID、command line、file provenance、首次出現時間
Schedule / timerScheduled TasksAuthor、principal、trigger、hidden flag、action path
Service startWindows services、driversService type、start mode、ImagePath、signer、ACL
Application loadDLL search order、COM registration、extensionsHost process、registration change、loaded module path
Event-drivenWMI subscription 等Filter、consumer、binding 與建立者

Autoruns 很適合做 cross-location inventory,但「有自動啟動項」不等於惡意。應回到 owner、change time、binary signer、command line、parent process 與 deployment context。

Defense Evasion 與 Anti-Analysis

常見樣本會延遲、分階段或條件式啟動。分析時把 evasive behavior 當成可量測條件:

  • Sleep / timer:比較 wall-clock、CPU time 與 timer objects。
  • Environment checks:記錄被查詢的 process、device、registry、firmware 與 system metadata。
  • Debugger checks:觀察控制流程分支,不急著修改所有 check。
  • Packing / obfuscation:找資料何時轉為 code、何時出現穩定 configuration。
  • Telemetry tampering:驗證 provider/module state 與 clean baseline 差異。
  • Unhooking / module replacement:比較 in-memory image、disk image、relocations 與合法 hotpatch。

最有價值的結果不是「成功騙過檢查」,而是列出每個 gate 的條件、true/false 路徑與它控制的 capability。這讓 sandbox 與 hunting team 能建立多組環境覆蓋不同分支。

Dynamic Analysis:建立時間線

將事件按照時間而非工具分類,可以避免各看各的:

Plain Text
T0  sample process created
T1  configuration / embedded resource read
T2  child process or target process opened
T3  memory allocation / mapping / write
T4  protection or thread context changed
T5  persistence artifact created
T6  DNS / network connection
T7  file cleanup or process termination

每個事件至少保留:timestamp、source PID/TID、target object、operation、result、stack 或 caller module(若有)、相關 hash/path 與收集來源。不同 telemetry 的 clocks 與 buffering 會造成順序偏差,因此保留原始時間與 correlation key。

Sysmon 能回答什麼?

Microsoft 將 Sysmon events 定位為 behavioral building blocks,而不是自動等於 alerts。常用關聯包括:

Event能提供的證據限制
Process CreateImage、command line、parent、hashParent 可受 execution chain 與 telemetry timing 影響
Network ConnectProcess 與 destination需啟用;看不到完整 application payload
Image LoadDLL/module load高流量,需精準 include strategy
CreateRemoteThread跨 process thread creation只覆蓋特定 injection family
Process AccessSource/target 與 requested access非常吵,需針對敏感 target 與 access mask
Process TamperingHollowing 等 process image manipulation有價值但不能覆蓋所有 memory execution
File / Registry events落地與 persistence artifacts需與 process GUID 及 timeline 關聯

MITRE ATT&CK Enterprise — click a tactic

Initial Access (TA0001)

Example techniques: Spearphishing, Exploit public-facing app

Network 與 C2 分析

不要只抽 IP/domain。完整 network profile 應包括:

  • DNS query pattern、TTL、fallback 與 failed resolutions。
  • Connection interval、jitter、session duration、bytes in/out。
  • HTTP method、URI shape、header order、user-agent consistency。
  • TLS SNI、certificate、ALPN、version 與可用的 fingerprint。
  • Proxy awareness、system proxy 使用方式與 credential context。
  • Request/response framing、message type、sequence number 與 retry logic。

對 encrypted traffic,重點通常是 metadata 與 endpoint behavior。若在授權 lab 中能從 process memory 或 instrumentation 取得 pre-encryption data,應清楚標記取得點與 chain of custody,不要把解密後內容誤當 wire bytes。

逆向註解:讓分析結果可以交接

我會把註解分成五層:

  1. Semantic:函式真正做什麼。
  2. State:輸入、輸出、global state 與 object lifetime。
  3. Capability:這段支援哪個能力或 ATT&CK behavior。
  4. Evidence:判斷依據與尚未確認的假設。
  5. Detection:可在 endpoint、memory 或 network 哪裡觀察。

建議命名帶上信心程度,例如 decrypt_config_probable、resolve_api_hash_confirmed,而不是一開始就命名成特定 malware family。重要結構應還原 field offset、size、encoding、ownership 與使用點;call graph 上則標記 dispatcher、parser、crypto wrapper、transport 與 task handlers。

Function summary 範本

Plain Text
Name: parse_config_confirmed
Inputs: blob pointer, blob length
Outputs: validated config object or error
Side effects: allocates heap object; updates global campaign id
Evidence: 4 call sites; length checks; decoded fields consumed by network init
Open questions: field 0x24 meaning; optional extension after version 3
Detection value: mutex format and URI path become stable after this stage

從 IOC 提升到 Detection Engineering

層級範例優缺點
AtomicHash、IP、domain、mutex精準但容易更換,壽命短
StructuralPE layout、config schema、protocol framing較穩定,需要 reverse engineering
BehavioralCross-process memory + anomalous execution能跨變種,但需要 context 降低誤報
StrategicCampaign infrastructure 與 operator workflow適合 hunting/CTI,歸因門檻高

高品質 detection 應包含 positive logic、known-good exclusions、required telemetry、performance cost、test corpus、預期 false positives 與失效條件。Rule 命中後要能告訴 analyst 下一步收集什麼,而不只是顯示「suspicious」。

報告應回答的問題

一份完整 malware report 至少要能回答:

  1. 樣本身分與分析環境是什麼?
  2. 執行需要哪些條件,哪些 branch 尚未覆蓋?
  3. Capability 與 execution chain 是什麼?
  4. 建立、修改或存取了哪些 objects 與 artifacts?
  5. Memory、persistence 與 network 證據如何互相支持?
  6. 哪些判斷已確認,哪些仍是推測?
  7. 可立即封鎖什麼、可長期偵測什麼?
  8. 清除後如何驗證沒有殘留,何時應直接重建主機?

常見誤區

  • 看到 high entropy 就說加密:壓縮與媒體資料也可能高 entropy。
  • 看到 RWX 就說 injection:需要 writer、executor 與 provenance。
  • 只收 IOC、不寫行為鏈:IOC 很快失效,分析價值無法延伸。
  • 把 sandbox 沒行為當安全:可能是條件未滿足、延遲或 telemetry 缺口。
  • 依 process name 判斷合法:要看 path、signer、token、parent、memory 與行為。
  • 將 ATT&CK technique 當檢測規則:ATT&CK 是行為分類,仍需具體 telemetry 與 analytic。
  • 修改樣本太早:Patch 可能改變控制流程,使原始行為與報告失去一致性。

延伸閱讀

最終目標不是「重現攻擊者的每一行程式碼」,而是把 execution、memory、persistence 與 network 轉成可驗證、可交接、可偵測的證據鏈。