Common API used in Malware

Reading time: 6 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Generic

Networking

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

Persistence

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

Encryption

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

Anti-Analysis/VM

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

Stealth

Name
VirtualAllocAlokacja pamięci (pakery)
VirtualProtectZmiana uprawnień pamięci (pakery nadające uprawnienia do wykonania sekcji)
ReadProcessMemoryWstrzykiwanie do zewnętrznych procesów
WriteProcessMemoryA/WWstrzykiwanie do zewnętrznych procesów
NtWriteVirtualMemory
CreateRemoteThreadWstrzykiwanie DLL/procesu...
NtUnmapViewOfSection
QueueUserAPC
CreateProcessInternalA/W

Execution

Function Name
CreateProcessA/W
ShellExecute
WinExec
ResumeThread
NtResumeThread

Miscellaneous

  • GetAsyncKeyState() -- Rejestrowanie klawiszy
  • SetWindowsHookEx -- Rejestrowanie klawiszy
  • GetForeGroundWindow -- Uzyskanie nazwy działającego okna (lub strony internetowej z przeglądarki)
  • LoadLibrary() -- Importowanie biblioteki
  • GetProcAddress() -- Importowanie biblioteki
  • CreateToolhelp32Snapshot() -- Lista działających procesów
  • GetDC() -- Zrzut ekranu
  • BitBlt() -- Zrzut ekranu
  • InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- Dostęp do Internetu
  • FindResource(), LoadResource(), LockResource() -- Dostęp do zasobów wykonywalnego

Malware Techniques

DLL Injection

Wykonaj dowolną DLL wewnątrz innego procesu

  1. Zlokalizuj proces, do którego wstrzykniesz złośliwą DLL: CreateToolhelp32Snapshot, Process32First, Process32Next
  2. Otwórz proces: GetModuleHandle, GetProcAddress, OpenProcess
  3. Zapisz ścieżkę do DLL wewnątrz procesu: VirtualAllocEx, WriteProcessMemory
  4. Utwórz wątek w procesie, który załaduje złośliwą DLL: CreateRemoteThread, LoadLibrary

Inne funkcje do użycia: NTCreateThreadEx, RtlCreateUserThread

Reflective DLL Injection

Załaduj złośliwą DLL bez wywoływania normalnych wywołań API systemu Windows.
DLL jest mapowana wewnątrz procesu, rozwiązuje adresy importu, naprawia relokacje i wywołuje funkcję DllMain.

Thread Hijacking

Znajdź wątek z procesu i spraw, aby załadował złośliwą DLL

  1. Znajdź docelowy wątek: CreateToolhelp32Snapshot, Thread32First, Thread32Next
  2. Otwórz wątek: OpenThread
  3. Wstrzymaj wątek: SuspendThread
  4. Zapisz ścieżkę do złośliwej DLL wewnątrz procesu ofiary: VirtualAllocEx, WriteProcessMemory
  5. Wznów wątek ładujący bibliotekę: ResumeThread

PE Injection

Wstrzykiwanie Portable Execution: Wykonywalny plik zostanie zapisany w pamięci procesu ofiary i będzie wykonywany stamtąd.

Process Hollowing (a.k.a RunPE)

Process Hollowing to jeden z ulubionych trików omijania obrony / wykonania używanych przez złośliwe oprogramowanie Windows. Idea polega na uruchomieniu legitymnego procesu w stanie wstrzymanym, usunięciu (hollow) jego oryginalnego obrazu z pamięci i skopiowaniu dowolnego PE w jego miejsce. Gdy główny wątek zostanie w końcu wznowiony, złośliwy punkt wejścia wykonuje się pod przykrywką zaufanego binarnego (często podpisanego przez Microsoft).

Typowy przebieg:

  1. Uruchom benigny host (np. RegAsm.exe, rundll32.exe, msbuild.exe) wstrzymany, aby żadne instrukcje jeszcze się nie wykonywały.
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. Odczytaj złośliwy ładunek do pamięci i przeanalizuj jego nagłówki PE, aby uzyskać SizeOfImage, sekcje i nowy EntryPoint.
  2. NtUnmapViewOfSection / ZwUnmapViewOfSection – odmapuj oryginalną bazę obrazu wstrzymanego procesu.
  3. VirtualAllocEx – zarezerwuj pamięć RWX o SizeOfImage wewnątrz zdalnego procesu.
  4. WriteProcessMemory – najpierw skopiuj Headers, a następnie iteruj przez sekcje, kopiując ich surowe dane.
  5. SetThreadContext – popraw wartość EAX/RAX (RCX na x64) lub Rip w strukturze kontekstu, aby EIP wskazywał na EntryPoint ładunku.
  6. ResumeThread – wątek kontynuuje, wykonując kod dostarczony przez atakującego.

Minimalny dowód koncepcji (x86) szkielet:

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

Praktyczne uwagi zaobserwowane w kampanii DarkCloud Stealer:

  • Loader wybrał RegAsm.exe (część .NET Framework) jako hosta – podpisany plik binarny, który prawdopodobnie nie przyciągnie uwagi.
  • Zdekompresowany stealer VB6 (holographies.exe) nie jest zapisywany na dysku; istnieje tylko w wewnętrznym procesie, co utrudnia statyczne wykrywanie.
  • Wrażliwe ciągi (regexy, ścieżki, dane uwierzytelniające Telegram) są szyfrowane RC4 dla każdego ciągu i są odszyfrowywane tylko w czasie wykonywania, co dodatkowo komplikuje skanowanie pamięci.

Pomysły na wykrywanie:

  • Alarmuj na procesy CREATE_SUSPENDED, które nigdy nie tworzą okien GUI/konsoli przed przydzieleniem regionu pamięci jako RWX (rzadkie dla kodu benignnego).
  • Szukaj sekwencji wywołań NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory w różnych procesach.

Hooking

  • SSDT (System Service Descriptor Table) wskazuje na funkcje jądra (ntoskrnl.exe) lub sterownik GUI (win32k.sys), aby procesy użytkownika mogły wywoływać te funkcje.
  • Rootkit może modyfikować te wskaźniki do adresów, które kontroluje.
  • IRP (I/O Request Packets) przesyłają fragmenty danych z jednego komponentu do drugiego. Prawie wszystko w jądrze używa IRP, a każdy obiekt urządzenia ma swoją własną tabelę funkcji, która może być hookowana: DKOM (Direct Kernel Object Manipulation).
  • IAT (Import Address Table) jest przydatna do rozwiązywania zależności. Możliwe jest hookowanie tej tabeli w celu przejęcia kodu, który będzie wywoływany.
  • EAT (Export Address Table) Hooki. Te hooki mogą być realizowane z userland. Celem jest hookowanie funkcji eksportowanych przez DLL.
  • Inline Hooks: Ten typ jest trudny do osiągnięcia. Polega na modyfikacji kodu samych funkcji. Może to być zrealizowane poprzez umieszczenie skoku na początku tej funkcji.

References

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks