Napisałem kod wywołujący ROP, który wywołujemprotect przez syscall, po wywołaniu int 0x80 eax jest ustawione na 0x0 wskazując na sukces. Przesunięcie wykonania do adresu docelowego nadal daje wynik SIGSEGV. Chciałbym, żeby ktoś pokazał mi, gdzie się nie mylę.
Niektóre szczegóły, adres docelowy to sekcja .data, tutaj będę pisał przez shellcode do:
[20] 0x8146820->0x814c2b8 at 0x000fd820: .data ALLOC LOAD DATA HAS_CONTENTS
ustawiłem eax
do 125
, ebx
do granicy strony 0x8146000
, ecx
do 0x1000
(4096 rozmiar strony) i edx
do 0x7
(RWX).
Tuż przed syscallem rejestry wyglądają tak:
eax 0x7d 125
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0182 0x80c0182 <mprotect+18>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) disas $eip, $eip+20
Dump of assembler code from 0x80c0182 to 0x80c0196:
=> 0x080c0182 <mprotect+18>: int $0x80
0x080c0184 <mprotect+20>: pop %ebx
0x080c0185 <mprotect+21>: cmp $0xfffff001,%eax
0x080c018a <mprotect+26>: jae 0x80c7d80 <__syscall_error>
0x080c0190 <mprotect+32>: ret
a po syscall rejestrach jest:
(gdb) si
0x080c0184 in mprotect ()
(gdb) i r
eax 0x0 0
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0184 0x80c0184 <mprotect+20>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
Jednak lokalizacja pamięci nie pokazuje zmiany w uprawnieniach i próba wykonania instrukcji kończy aplikację:
(gdb) x/4x 0x8146820
0x8146820: 0x00000000 0x00000000 0x08146154 0x0000ea60
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08146820 in data_start ()
Wszelkie sugestie dotyczące tego, jak / co debugować lub co robię źle są mile widziane.
Edytować Uruchomiłem to pod strace bez dołączonego debuggera, wygląda na to, że wywołanie mprotect jest sukcesem, ale wykonanie się nie powiedzie:
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2197, ...}) = 0
mprotect(0x8146000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
+++ killed by SIGSEGV (core dumped) +++
Potwierdzanie adresu awarii z rdzenia:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08146820 in data_start ()
Odpowiedzi:
5 dla odpowiedzi № 1Twoje połączenie mprotect zadziałało. Program ulega awarii, ponieważ 0x8146820
trzyma
0x0000
, który rozkłada się na add [eax], al
, i eax
trzyma zero. Ale adres 0
nie jest mapowany. (Właśnie dlatego w tym segfault jest si_addr=0
)