controllo flusso (buffer overflow) (domanda introduttiva)

2

Sto guardando il seguente codice e sto cercando di capire come questo bug sarebbe utile per qualcosa come lanciare una shell.

int func(int i, double *data1, double data2) 
{

double  *p = data1;       
double  *vec[10];

if ((i<0) || (i>10)) return;   

vec[i] = data1; 
*p = data2;     

}

C'è una risposta sul pdf collegato qui sotto ( Send i = 10 and data1 = RetAddr ) ma sto cercando una spiegazione più elaborata.

La domanda viene dalla classe CS 155 di Dan Boneh e qui è la # 3:

posta Nathan Reitinger 07.12.2017 - 21:04
fonte

1 risposta

1

La risposta breve è che l'indice 10 è oltre i limiti della matrice vec e scrivere un doppio di 8 byte su vec[10] potrebbe sovrascrivere il puntatore di base della funzione precedente e l'indirizzo di risposta della funzione - a seconda di come il compilatore alloca la memoria sullo stack per le variabili locali.

Ecco un diagramma dello stack di runtime quando è stato chiamato func (si presume l'architettura x86):

 <------------ 4 bytes ----------->
                 .
                 .
                 .
 +---------------------------------+
 |             data2               |
 +---------------------------------+  arg 3 (8 bytes)
 |             data2               |
 +---------------------------------+  
 |             data1               |
 +---------------------------------+  arg 2 (8 bytes)
 |             data1               |
 +---------------------------------+
 |               i                 |  arg 1 
 +---------------------------------+
 |         return address          |                 < 8 bytes to      <--\
 +---------------------------------+                 < be overwritten      |
 | previous ebp (old base pointer) |  <-- "vec[10]"  < by data1            |
 +---------------------------------+                                       |  stack
 |             vec[9]              |                                       |  frame
 +---------------------------------+                                       |  for
 |             vec[8]              |                                       |  "func"
 +---------------------------------+                                       |
                 .                                                         |
                 .                                                         |
                 .                                                         |
 +---------------------------------+                                       |
 |             vec[1]              |                                       |
 +---------------------------------+                                       |
 |             vec[0]              |                                   <--/
 +---------------------------------+

Si noti che la disposizione della memoria allocata per le variabili locali in uno stack frame è determinata dal compilatore. Ciò significa che l'allineamento dello stack può comportare "spazio allentato" che, ad esempio, elimina il calcolo dell'offset del buffer. Inoltre, se il compilatore alloca la memoria per la variabile p tra il ebp salvato e la memoria allocata per l'array vec , p verrà sovrascritto anziché il vecchio ebp e l'indirizzo di ritorno di func .

Per maggiori informazioni sul layout dello stack frame vedi:

risposta data 07.12.2017 - 23:51
fonte

Leggi altre domande sui tag