c - poner - meta tags html
No se puede entender un código de explotación de cadena de formato (2)
En la entrada a snprintf
, la pila tiene lo siguiente:
0xbfd257d0: 0xxxxxxxxx 0xxxxxxxxx 0xxxxxxxxx 0x080484d5
0xbfd257e0: 0xbfd25800 0x00000200 0xbfd25a00 0x00000000
0xbfd257f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfd25800: 0x00000000 0x00000040 0xb7f22f2c 0x00000000
0xbfd25810: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfd25800 -> target (initially 0x00000000 0x00000040 ...)
... -> garbage
0xbfd257e8 -> pointer to buffer
0xbfd257e4 -> 512
0xbfd257e0 -> pointer to target
0xbfd257df -> return address
target
se sobrescribe con el resultado de snprintf
antes de que snprintf
use sus palabras como argumentos: Primero escribe "AAAA" (0x41414141) en 0xbfd25800, luego "% x" lee el valor en 0xbfd257ec y lo escribe en 0xbfd25804, ..., entonces "% x" lee el valor en 0xbfd25800 (0x41414141) y lo escribe en 0xbfd25814, ...
Encontré este código que muestra la explotación de cadenas de formato mientras leía this artículo.
#include <stdio.h>
int main(void)
{
char secret[]="hack.se is lame";
char buffer[512];
char target[512];
printf("secret = %pn",&secret);
fgets(buffer,512,stdin);
snprintf(target,512,buffer);
printf("%s",target);
}
Ejecutándolo con la siguiente entrada
[root@knark]$ ./a.out
secret = 0xbffffc68
AAAA%x %x %x %x %x %x %x //Input given
AAAA4013fe20 0 0 0 41414141 33313034 30326566
- [root@knark]$
Lo que entiendo hasta ahora es que la secuencia de %x
''s seguirá imprimiendo los valores en las direcciones por encima del %esp
actual (supongo que la pila está creciendo hacia abajo hacia la dirección más baja).
Lo que no puedo entender es que la entrada dada se almacena en una matriz de buffer
que no puede estar a menos de 512 bytes de la actual %esp
. Entonces, ¿cómo puede la salida contener 41414141
(la representación hexadecimal de AAAA
) justo después del 4 %x
, es decir, justo por encima de las 4 direcciones de %esp
actual? También intenté fijarme en el código de ensamblaje, pero creo que no podía seguir la manipulación de las cadenas en la pila.
En primer lugar, echemos un vistazo a la pila después de llamar a snprintf ():
Reading symbols from /home/blackbear/a.out...done.
(gdb) run
Starting program: /home/blackbear/a.out
secret = 0xbffff40c
ABCDEF%x %x %x %x %x %x %x
Breakpoint 1, main () at prova.c:13
13 printf("%s",target);
(gdb) x/20x $esp
0xbfffeff0: 0xbffff00c 0x00000200 0xbffff20c 0x00155d7c
0xbffff000: 0x00155d7c 0x000000f0 0x000000f0 0x44434241
0xbffff010: 0x35314645 0x63376435 0x35353120 0x20633764
0xbffff020: 0x66203066 0x34342030 0x32343334 0x33203134
0xbffff030: 0x34313335 0x20353436 0x37333336 0x35333436
(gdb)
Realmente podemos ver, en 0xbffff00c, la cadena ya formateada, por lo que sprintf () escribió allí mismo. También podemos ver, en 0xbfffeff0, el último argumento para snprintf (): la dirección de destino, que en realidad es 0xbffff00c. Así que puedo deducir que las cadenas se guardan desde el final hasta el principio de su espacio asignado en la pila, como también podemos ver agregando un strcpy ():
blackbear@blackbear-laptop:~$ cat prova.c
#include <stdio.h>
#include <string.h>
int main(void)
{
char secret[]="hack.se is lame";
char buffer[512];
char target[512];
printf("secret = %p/n", &secret);
strcpy(target, "ABCDEF");
fgets(buffer,512,stdin);
snprintf(target,512,buffer);
printf("%s",target);
}
blackbear@blackbear-laptop:~$ gcc prova.c -g
prova.c: In function ‘main’:
prova.c:14: warning: format not a string literal and no format arguments
prova.c:14: warning: format not a string literal and no format arguments
blackbear@blackbear-laptop:~$ gdb ./a.out -q
Reading symbols from /home/blackbear/a.out...done.
(gdb) break 13
Breakpoint 1 at 0x8048580: file prova.c, line 13.
(gdb) run
Starting program: /home/blackbear/a.out
secret = 0xbffff40c
Breakpoint 1, main () at prova.c:13
13 fgets(buffer,512,stdin);
(gdb) x/10x $esp
0xbfffeff0: 0xbffff00c 0x080486bd 0x00000007 0x00155d7c
0xbffff000: 0x00155d7c 0x000000f0 0x000000f0 0x44434241
0xbffff010: 0x00004645 0x00000004
(gdb)
¡Eso es! En conclusión, hemos encontrado la cadena allí porque las cadenas se almacenan en la pila de forma inversa, y el principio (o el final?) Del objetivo está cerca de la esp.