Malware에서 사용되는 일반 API

Reading time: 6 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. benign host 생성 (예: 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. SetThreadContextEAX/RAX (RCX on x64) 또는 컨텍스트 구조의 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);
}

Practical notes observed in the DarkCloud Stealer campaign:

  • 로더는 주목을 끌 가능성이 낮은 서명된 바이너리인 RegAsm.exe (.NET Framework의 일부)를 호스트로 선택했습니다.
  • 복호화된 VB6 스틸러(holographies.exe)는 디스크에 드롭되지 않으며, 오직 비워진 프로세스 내에서만 존재하여 정적 탐지를 더 어렵게 만듭니다.
  • 민감한 문자열(정규 표현식, 경로, 텔레그램 자격 증명)은 문자열별로 RC4-암호화되어 있으며, 런타임에서만 복호화되어 메모리 스캔을 더욱 복잡하게 만듭니다.

Detection ideas:

  • 메모리 영역이 RWX로 할당되기 전에 GUI/콘솔 창을 생성하지 않는 CREATE_SUSPENDED 프로세스에 경고합니다 (선량한 코드에서는 드물게 발생).
  • 서로 다른 프로세스에서 NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory 호출 시퀀스를 찾습니다.

Hooking

  • SSDT (System Service Descriptor Table)는 사용자 프로세스가 이러한 함수를 호출할 수 있도록 커널 함수(ntoskrnl.exe) 또는 GUI 드라이버(win32k.sys)를 가리킵니다.
  • 루트킷은 이러한 포인터를 자신이 제어하는 주소로 수정할 수 있습니다.
  • IRP (I/O Request Packets)는 한 구성 요소에서 다른 구성 요소로 데이터를 전송합니다. 커널의 거의 모든 것이 IRP를 사용하며, 각 장치 객체는 후킹할 수 있는 자체 함수 테이블을 가지고 있습니다: DKOM (Direct Kernel Object Manipulation)
  • IAT (Import Address Table)는 종속성을 해결하는 데 유용합니다. 이 테이블을 후킹하여 호출될 코드를 가로챌 수 있습니다.
  • EAT (Export Address Table) 후킹. 이 후킹은 userland에서 수행될 수 있습니다. 목표는 DLL에 의해 내보내진 함수를 후킹하는 것입니다.
  • Inline Hooks: 이 유형은 달성하기 어렵습니다. 이는 함수 자체의 코드를 수정하는 것을 포함합니다. 아마도 이의 시작 부분에 점프를 넣는 방식으로.

References

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 지원하기