Malware์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ณตํ†ต API

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()

TLS pinning ๋ฐ chunked transport

๋งŽ์€ loaders๋Š” TCP ์ŠคํŠธ๋ฆผ์„ SslStream์œผ๋กœ ๋ž˜ํ•‘ํ•˜๊ณ  ์„œ๋ฒ„์˜ leaf certificate๋ฅผ ์ž„๋ฒ ๋””๋“œ ๋ณต์‚ฌ๋ณธ๊ณผ ๋น„๊ตํ•˜์—ฌ ๊ณ ์ •(certificate pinning)ํ•ฉ๋‹ˆ๋‹ค. Bot ์ •๋ณด/์ž‘์—…์€ ์••์ถ•๋˜์–ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค(์˜ˆ: GZip). ์‘๋‹ต์ด ์ž„๊ณ„๊ฐ’(์•ฝ 1 MB)์„ ์ดˆ๊ณผํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๋Š” ์‚ฌ์ด์ฆˆ ๊ธฐ๋ฐ˜ ํœด๋ฆฌ์Šคํ‹ฑ์„ ํšŒํ”ผํ•˜๊ณ  ์—ญ์ง๋ ฌํ™” ๋™์•ˆ ๋ฉ”๋ชจ๋ฆฌ ๊ธ‰์ฆ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ž‘์€ ์ฒญํฌ(์˜ˆ: 16 KB ์„ธ๊ทธ๋จผํŠธ)๋กœ ๋ถ„ํ• ๋ฉ๋‹ˆ๋‹ค.

Persistence

RegistryFileService
RegCreateKeyEx()GetTempPath()OpenSCManager
RegOpenKeyEx()CopyFile()CreateService()
RegSetValueEx()CreateFile()StartServiceCtrlDispatcher()
RegDeleteKeyEx()WriteFile()
RegGetValue()ReadFile()

์•”ํ˜ธํ™”

Name
WinCrypt
CryptAcquireContext()
CryptGenKey()
CryptDeriveKey()
CryptDecrypt()
CryptReleaseContext()

์•ˆํ‹ฐ ๋ถ„์„/VM

Function NameAssembly Instructions
IsDebuggerPresent()CPUID()
GetSystemInfo()IN()
GlobalMemoryStatusEx()
GetVersion()
CreateToolhelp32Snapshot [Check if a process is running]
CreateFileW/A [Check if a file exist]

๋กœ์ผ€์ผ/ํ‚ค๋ณด๋“œ ๊ธฐ๋ฐ˜ ์‹คํ–‰ ๊ฐ€๋“œ

๋งŽ์€ stealers/loaders๋Š” ์—ฐ๊ตฌ์ž๋ฅผ ํšŒํ”ผํ•˜๊ณ  ์œ„ํ˜‘ ํ–‰์œ„์ž์˜ ์ œ์•ฝ์„ ์ค€์ˆ˜ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • ๋กœ์ผ€์ผ์—์„œ ์‹คํ–‰์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์ฒดํฌ:

  • GetKeyboardLayout to enumerate installed layouts (per-thread/user)
  • GetLocaleInfoA/W to resolve country/region codes
  • GetSystemDefaultLangID / GetUserDefaultLangID

๋งŒ์•ฝ ์–ด๋–ค ํ•ญ๋ชฉ์ด๋ผ๋„ ์ฐจ๋‹จ ๋ชฉ๋ก(์ผ๋ฐ˜์ ์œผ๋กœ CIS countries)๊ณผ ์ผ์น˜ํ•˜๋ฉด, loader๋Š” network IOCs ๋˜๋Š” injection ์ „์— ์ฆ‰์‹œ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

๋ฐฉ์–ด/ํ—ŒํŒ…

  • ์‹คํ–‰ ์ดˆ๊ธฐ์— ์—ฌ๋Ÿฌ ๋กœ์ผ€์ผ/ํ‚ค๋ณด๋“œ API๋ฅผ ์กฐํšŒํ•œ ๋’ค ์•„๋ฌด๋Ÿฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ™œ๋™ ์—†์ด ์ข…๋ฃŒํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ํ”Œ๋ž˜๊ทธ๋กœ ํ‘œ์‹œํ•˜์„ธ์š”.
  • ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ(์˜ˆ: VMDetector)์—์„œ ์žฌ์‚ฌ์šฉ๋˜๋Š” anti-VM ๊ฒ€์‚ฌ(BIOS strings, PnP devices, disk model, services)์™€ ์ƒ๊ด€๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค์–ด gated execution์„ ํƒ์ง€ํ•˜์„ธ์š”.

์—๋ฎฌ๋ ˆ์ดํ„ฐ API ์ง€๋ฌธํ™” ๋ฐ ์Šฌ๋ฆฝ ํšŒํ”ผ

Malware๋Š” ์ข…์ข… Defender์˜ virtualised exports(=Malware Protection Emulator์—์„œ ๊ด€์ฐฐ๋œ)๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์ƒŒ๋“œ๋ฐ•์Šค ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์ง€๋ฌธํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‹ฌ๋ณผ์ด ํ”„๋กœ์„ธ์Šค์— ์กด์žฌํ•˜๋ฉด(ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ์—†๋Š” ์Šค์บ”), ์‹คํ–‰์€ 10โ€“30๋ถ„ ๋™์•ˆ ์ง€์—ฐ๋˜๊ณ  ์žฌํ™•์ธ๋˜์–ด ๋ถ„์„ ์‹œ๊ฐ„์„ ๋‚ญ๋น„์‹œํ‚ต๋‹ˆ๋‹ค.

Examples of API names used as canaries:

  • MpVmp32Entry, MpVmp32FastEnter, MpCallPreEntryPointCode, MpCallPostEntryPointCode, MpFinalize, MpReportEvent*, MpSwitchToNextThread*
  • VFS_* family: VFS_Open, VFS_Read, VFS_MapViewOfFile, VFS_UnmapViewOfFile, VFS_FindFirstFile/FindNextFile, VFS_CopyFile, VFS_DeleteFile, VFS_MoveFile
  • ThrdMgr_*: ThrdMgr_GetCurrentThreadHandle, ThrdMgr_SaveTEB, ThrdMgr_SwitchThreads

Typical delay primitive (user-land):

cmd /c timeout /t %RANDOM_IN_[600,1800]% > nul

Argument gatekeeping

  • ์šด์˜์ž๋Š” ํŽ˜์ด๋กœ๋“œ ์‹คํ–‰ ์ „์— ๋ฌดํ•ดํ•ด ๋ณด์ด๋Š” CLI ์Šค์œ„์น˜๊ฐ€ ์กด์žฌํ•  ๊ฒƒ์„ ์š”๊ตฌํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค(์˜ˆ: Chromium ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ‰๋‚ด๋‚ด๊ธฐ ์œ„ํ•œ /i:--type=renderer). ์Šค์œ„์น˜๊ฐ€ ์—†์œผ๋ฉด ๋กœ๋”๋Š” ์ฆ‰์‹œ ์ข…๋ฃŒ๋˜์–ด ๋‹จ์ˆœํ•œ ์ƒŒ๋“œ๋ฐ•์Šค ์‹คํ–‰์„ ๋ฐฉํ•ดํ•œ๋‹ค.

์€ํ

Name
VirtualAlloc๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น (ํŒจ์ปค)
VirtualProtect๋ฉ”๋ชจ๋ฆฌ ๊ถŒํ•œ ๋ณ€๊ฒฝ (์„น์…˜์— ์‹คํ–‰ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ํŒจ์ปค)
ReadProcessMemory์™ธ๋ถ€ ํ”„๋กœ์„ธ์Šค ์ฃผ์ž…
WriteProcessMemoryA/W์™ธ๋ถ€ ํ”„๋กœ์„ธ์Šค ์ฃผ์ž…
NtWriteVirtualMemory
CreateRemoteThreadDLL/Process injectionโ€ฆ
NtUnmapViewOfSection
QueueUserAPC
CreateProcessInternalA/W

์‹คํ–‰

Function Name
CreateProcessA/W
ShellExecute
WinExec
ResumeThread
NtResumeThread

๊ธฐํƒ€

  • GetAsyncKeyState() โ€“ Key logging
  • SetWindowsHookEx โ€“ Key logging
  • GetForeGroundWindow โ€“ ์‹คํ–‰ ์ค‘์ธ ์ฐฝ ์ด๋ฆ„ ๊ฐ€์ ธ์˜ค๊ธฐ (๋˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์›น์‚ฌ์ดํŠธ)
  • LoadLibrary() โ€“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋กœ๋“œ
  • GetProcAddress() โ€“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜ ์ฃผ์†Œ ์กฐํšŒ
  • CreateToolhelp32Snapshot() โ€“ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค ๋‚˜์—ด
  • GetDC() โ€“ ํ™”๋ฉด ์บก์ฒ˜
  • BitBlt() โ€“ ํ™”๋ฉด ์บก์ฒ˜
  • InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() โ€“ ์ธํ„ฐ๋„ท ์ ‘๊ทผ
  • FindResource(), LoadResource(), LockResource() โ€“ ์‹คํ–‰ ํŒŒ์ผ์˜ ๋ฆฌ์†Œ์Šค ์ ‘๊ทผ

์•…์„ฑ์ฝ”๋“œ ๊ธฐ๋ฒ•

DLL Injection

Execute an arbitrary DLL inside another process

  1. Locate the process to inject the malicious DLL: CreateToolhelp32Snapshot, Process32First, Process32Next
    ์•…์„ฑ DLL์„ ์ฃผ์ž…ํ•  ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฐพ๋Š”๋‹ค: CreateToolhelp32Snapshot, Process32First, Process32Next
  2. Open the process: GetModuleHandle, GetProcAddress, OpenProcess
    ํ”„๋กœ์„ธ์Šค๋ฅผ ์—ฐ๋‹ค: GetModuleHandle, GetProcAddress, OpenProcess
  3. Write the path to the DLL inside the process: VirtualAllocEx, WriteProcessMemory
    ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์— DLL ๊ฒฝ๋กœ๋ฅผ ์“ด๋‹ค: VirtualAllocEx, WriteProcessMemory
  4. Create a thread in the process that will load the malicious DLL: CreateRemoteThread, LoadLibrary
    ์•…์„ฑ DLL์„ ๋กœ๋“œํ•  ์Šค๋ ˆ๋“œ๋ฅผ ํ”„๋กœ์„ธ์Šค ๋‚ด์— ์ƒ์„ฑํ•œ๋‹ค: CreateRemoteThread, LoadLibrary

Other functions to use: NTCreateThreadEx, RtlCreateUserThread

Reflective DLL Injection

Load a malicious DLL without calling normal Windows API calls.
The DLL is mapped inside a process, it will resolve the import addresses, fix the relocations and call the DllMain function.
ํ‘œ์ค€ Windows API ํ˜ธ์ถœ ์—†์ด ์•…์„ฑ DLL์„ ๋กœ๋“œํ•œ๋‹ค. DLL์ด ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์— ๋งคํ•‘๋˜๋ฉฐ ์ž„ํฌํŠธ ์ฃผ์†Œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žฌ๋ฐฐ์น˜(relocations)๋ฅผ ์ˆ˜์ •ํ•œ ๋’ค DllMain ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

Thread Hijacking

Find a thread from a process and make it load a malicious DLL

  1. Find a target thread: CreateToolhelp32Snapshot, Thread32First, Thread32Next
    ๋Œ€์ƒ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ๋Š”๋‹ค: CreateToolhelp32Snapshot, Thread32First, Thread32Next
  2. Open the thread: OpenThread
    ์Šค๋ ˆ๋“œ๋ฅผ ์—ฐ๋‹ค: OpenThread
  3. Suspend the thread: SuspendThread
    ์Šค๋ ˆ๋“œ๋ฅผ ์ผ์‹œ์ค‘๋‹จํ•œ๋‹ค: SuspendThread
  4. Write the path to the malicious DLL inside the victim process: VirtualAllocEx, WriteProcessMemory
    ํ”ผํ•ด์ž ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์— ์•…์„ฑ DLL ๊ฒฝ๋กœ๋ฅผ ์“ด๋‹ค: VirtualAllocEx, WriteProcessMemory
  5. Resume the thread loading the library: ResumeThread
    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋“œํ•˜๋„๋ก ์Šค๋ ˆ๋“œ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•œ๋‹ค: ResumeThread

PE Injection

Portable Execution Injection: The executable will be written in the memory of the victim process and it will be executed from there.
Portable Executable ์ฃผ์ž…: ์‹คํ–‰ ํŒŒ์ผ์ด ๋Œ€์ƒ ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ์— ๊ธฐ๋ก๋˜๊ณ  ๊ทธ๊ณณ์—์„œ ์‹คํ–‰๋œ๋‹ค.

Process Hollowing (a.k.a RunPE)

Process Hollowing is one of the favourite defence-evasion / execution tricks used by Windows malware. The idea is to launch a legitimate process in the suspended state, remove (hollow) its original image from memory and copy an arbitrary PE in its place. When the primary thread is finally resumed the malicious entry-point executes under the guise of a trusted binary (often signed by Microsoft).
Process Hollowing์€ Windows ์•…์„ฑ์ฝ”๋“œ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” defence-evasion / execution ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์•„์ด๋””์–ด๋Š” ์ •์ƒ์ ์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ผ์‹œ์ค‘๋‹จ ์ƒํƒœ๋กœ ์‹คํ–‰ํ•œ ํ›„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์›๋ž˜ ์ด๋ฏธ์ง€๋ฅผ ์ œ๊ฑฐ(๋น„์šฐ๊ธฐ)ํ•˜๊ณ  ๊ทธ ์ž๋ฆฌ์— ์ž„์˜์˜ PE๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฃผ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘๋˜๋ฉด ์•…์„ฑ ์—”ํŠธ๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ์‹ ๋ขฐ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ(์ข…์ข… Microsoft์— ์˜ํ•ด ์„œ๋ช…๋จ)๋กœ ๊ฐ€์žฅํ•˜์—ฌ ์‹คํ–‰๋œ๋‹ค.

Typical workflow:

  1. Spawn a benign host (e.g. RegAsm.exe, rundll32.exe, msbuild.exe) suspended so that no instructions run yet.
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);

๋ฌดํ•ดํ•œ ํ˜ธ์ŠคํŠธ(์˜ˆ: RegAsm.exe, rundll32.exe, msbuild.exe)๋ฅผ ์ผ์‹œ์ค‘๋‹จ ์ƒํƒœ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์•„์ง ์–ด๋–ค ๋ช…๋ น๋„ ์‹คํ–‰๋˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค. 2. Read the malicious payload into memory and parse its PE headers to obtain SizeOfImage, sections and the new EntryPoint.
์•…์„ฑ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์ฝ์–ด๋“ค์—ฌ PE ํ—ค๋”๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ SizeOfImage, ์„น์…˜ ๋ฐ ์ƒˆ EntryPoint๋ฅผ ์–ป๋Š”๋‹ค. 3. NtUnmapViewOfSection / ZwUnmapViewOfSection โ€“ unmap the original image base of the suspended process.
NtUnmapViewOfSection / ZwUnmapViewOfSection โ€“ ์ผ์‹œ์ค‘๋‹จ๋œ ํ”„๋กœ์„ธ์Šค์˜ ์›๋ž˜ ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค๋ฅผ ์–ธ๋งตํ•œ๋‹ค. 4. VirtualAllocEx โ€“ reserve RWX memory of SizeOfImage inside the remote process.
VirtualAllocEx โ€“ ์›๊ฒฉ ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์— SizeOfImage ํฌ๊ธฐ์˜ RWX ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์˜ˆ์•ฝํ•œ๋‹ค. 5. WriteProcessMemory โ€“ copy the Headers first, then iterate over sections copying their raw data.
WriteProcessMemory โ€“ ๋จผ์ € Headers๋ฅผ ๋ณต์‚ฌํ•œ ๋’ค ๊ฐ ์„น์…˜์˜ ์›์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๋ณต์‚ฌํ•œ๋‹ค. 6. SetThreadContext โ€“ patch the value of EAX/RAX (RCX on x64) or Rip in the context structure so that EIP points to the payloadโ€™s EntryPoint.
SetThreadContext โ€“ ์ปจํ…์ŠคํŠธ ๊ตฌ์กฐ์—์„œ EAX/RAX(x64์˜ ๊ฒฝ์šฐ RCX) ๋˜๋Š” Rip ๊ฐ’์„ ํŒจ์น˜ํ•˜์—ฌ EIP๊ฐ€ ํŽ˜์ด๋กœ๋“œ์˜ EntryPoint๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•œ๋‹ค. 7. ResumeThread โ€“ the thread continues, executing the attacker-supplied code.
ResumeThread โ€“ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์†๋˜์–ด ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

Minimal proof-of-concept (x86) skeleton:

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);
}

Practical notes observed in the DarkCloud Stealer campaign:

  • ๋กœ๋”๋Š” RegAsm.exe (.NET Framework์˜ ์ผ๋ถ€)๋ฅผ ํ˜ธ์ŠคํŠธ๋กœ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค โ€“ ์„œ๋ช…๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ์—ฌ์„œ ์ฃผ๋ชฉ์„ ๋œ ๋ฐ›์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
  • ๋ณตํ˜ธํ™”๋œ VB6 stealer (holographies.exe)๋Š” ๋””์Šคํฌ์— ๋“œ๋กญ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค; ์˜ค์ง hollowed process ๋‚ด๋ถ€์—์„œ๋งŒ ์กด์žฌํ•˜์—ฌ ์ •์  ํƒ์ง€๋ฅผ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ๋ฏผ๊ฐํ•œ ๋ฌธ์ž์—ด (regexes, paths, Telegram credentials)์€ ๋ฌธ์ž์—ด๋ณ„๋กœ RC4-encrypted ๋˜์–ด ๋Ÿฐํƒ€์ž„์—๋งŒ ๋ณตํ˜ธํ™”๋˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์Šค์บ”์„ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

Detection ideas:

  • ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด RWX๋กœ ํ• ๋‹น๋˜๊ธฐ ์ „์— GUI/console ์ฐฝ์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š” CREATE_SUSPENDED ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด ๊ฒฝ๋ณด๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค (์ •์ƒ ์ฝ”๋“œ์—์„  ๋“œ๋ญ…๋‹ˆ๋‹ค).
  • ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์—์„œ NtUnmapViewOfSection โžœ VirtualAllocEx โžœ WriteProcessMemory ํ˜ธ์ถœ ์‹œํ€€์Šค๋ฅผ ์ฐพ์•„๋ณด์„ธ์š”.
  • ํŠนํžˆ MSBuild.exe, RegAsm.exe, rundll32.exe ๊ฐ™์€ ์‹ ๋ขฐ๋ฐ›๋Š” ๊ฐœ๋ฐœ์ž ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ hollowing hosts๋กœ ๋น„์ •์ƒ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์งง๊ฒŒ ์‹คํ–‰๋˜๋Š” ๋กœ๋”๊ฐ€ ๋ถ€๋ชจ๋กœ ์žˆ๋Š” ๊ฒฝ์šฐ ์˜์‹ฌํ•˜์„ธ์š”.
  • ์‚ฌ์šฉ์ž ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๊ฒฝ๋กœ์—์„œ spawn๋˜๊ฑฐ๋‚˜ ๋Œ€์‘ํ•˜๋Š” .sln/.proj ์ปจํ…์ŠคํŠธ ์—†์ด ์ƒ์„ฑ๋˜์–ด ์™ธ๋ถ€ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” msbuild.exe๋ฅผ ์ฐพ์•„๋ณด์„ธ์š” (ATT&CK T1127.001 + T1055.012).

Common host processes and path resolution

  • MSBuild.exe๋Š” ๊ฐœ๋ฐœ ๋„๊ตฌ์™€ ์„ž์ด๊ธฐ ์œ„ํ•ด hollowing host๋กœ ์ž์ฃผ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. ๋กœ๋”๋Š” ์ข…์ข… ์•„ํ‚คํ…์ฒ˜์— ๋งž๋Š” ์œ„์น˜๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค:
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
  • C:\Windows\System32\MSBuild.exe
  • C:\Windows\SysWOW64\MSBuild.exe
  • ํ˜„์žฌ payload/OS ์•„ํ‚คํ…์ฒ˜์— ๋งž๋Š” ํ˜ธ์ŠคํŠธ๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ CreateProcess(..., CREATE_SUSPENDED, ...)๋ฅผ ํ˜ธ์ถœํ•˜์‹ญ์‹œ์˜ค.

Hooking

  • The SSDT (System Service Descriptor Table) points to kernel functions (ntoskrnl.exe) or GUI driver (win32k.sys) so user processes can call these functions.
  • rootkit์€ ์ด๋Ÿฌํ•œ ํฌ์ธํ„ฐ๋ฅผ ์ž์‹ ์ด ์ œ์–ดํ•˜๋Š” ์ฃผ์†Œ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • The IRP (I/O Request Packets) transmit pieces of data from one component to another. Almost everything in the kernel uses IRPs and each device object has its own function table that can be hooked: DKOM (Direct Kernel Object Manipulation)
  • The IAT (Import Address Table) is useful to resolve dependencies. Itโ€™s possible to hook this table in order to hijack the code that will be called.
  • EAT (Export Address Table) Hooks. This hooks can be done from userland. The goal is to hook exported functions by DLLs.
  • Inline Hooks: This type are difficult to achieve. This involve modifying the code of the functions itself. Maybe by putting a jump at the beginning of this.

์ฐธ๊ณ ์ž๋ฃŒ

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 ์ง€์›ํ•˜๊ธฐ