tag poner name keywords google generador etiquetas ejemplos como agregar c

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.