2009-11-15 5 views
8

Sono un po 'confuso nell'idea dell'iniezione di codice in C. Se qualcuno può spiegarlo e mostrare come è fatto, lo apprezzerei.Capire e fare codice di iniezione in C

Quindi diciamo che in C si dispone di un array Char di dimensione 512 che viene scritto sul contenuto di un socket di lunghezza 1024 e che l'array di caratteri contiene ora una sorta di codice ma solo la metà di ciò che è stato scritto.

Come viene eseguito il codice dannoso in un buffer overflow, penso di essere confuso sulla struttura del processo (stack, heap, dati, testo).

+3

È possibile accettare risposte su alcune delle domande precedenti facendo clic sulla casella di controllo accanto alla risposta corretta. –

+0

Grazie ragazzi non sapevo nemmeno di quella funzione. – Recursion

risposta

8

Il trucco generale ha a che fare con il modo in cui il codice e le variabili del programma sono disposti in memoria. Ad esempio, quando viene chiamata una funzione, il programma (codice inserito dal compilatore) deve memorizzare l'indirizzo dell'istruzione a cui tornare. Quindi, se questa è la parola a 32 bit poco prima dell'inizio della pila, si potrebbe fare:

void foo() 
{ 
    int array[5]; 
    int var = 0; 
    int var2 = 0; 

    // read in user input 
    printf("Enter index and value to write:"); 
    scanf("%i", var); 
    scanf("%i", var2); 

    // malicious user might set var to -1 and var2 to an address to execute 
    // if say the 32-bit value before the stack variables is the instruction to 
    // return to 
    array[var] = var2 

    // return now goes to malicious code 
} 

(. Così il vostro compito è quello di costruire codice in modo che una cosa del genere non è possibile :))

Le regole per il modo in cui una chiamata di funzione viene implementata, le variabili di stack allocate, i valori passati e i valori di ritorno restituiti si chiama calling convention. Raccomando di leggere l'articolo allegato per una buona copertura approfondita delle convenzioni di chiamata C.

0

Una pila tipico per ciascuna subroutine potrebbe essere simile a questo:

  • parametri (valori che sono stati passati come parametri a questa subroutine)
  • indirizzo di ritorno (indirizzo del codice da cui è stato chiamato questa routine)
  • valori di registro salvati
  • variabili locali

Se una subroutine ha un variabl locale e, e in qualche modo scrivere oltre la fine della variabile locale, quindi sovrascrive i valori (sullo stack) come l'indirizzo di ritorno, cioè l'indirizzo del codice che verrà eseguito alla fine della subroutine quando la subroutine fa un "ritorno" ".

2

Se si alloca un buffer nello stack e si rovescia, esso scrive nello stack. Lo stack contiene il puntatore di ritorno per la funzione che ha allocato il buffer. Quindi, se si rovescia un buffer nello stack, è possibile impostare il puntatore di ritorno su qualcosa di arbitrario; quindi dandoti il ​​controllo del thread di esecuzione.

Come per iniettare effettivamente il codice, dipende. Lo stack - o meglio, la pagina che lo contiene - è spesso impostato per non consentire l'esecuzione del codice; ma storicamente sarebbe stato possibile archiviare piccoli programmi maligni nel buffer stesso nello stack. Return oriented programming è una variante relativamente nuova dell'attacco return-to-libc, che funzionano entrambi attorno ai bit NX.

Problemi correlati