Ret2esp / Ret2reg
Last updated
Last updated
Ucz się i praktykuj Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i praktykuj Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ponieważ ESP (Wskaźnik stosu) zawsze wskazuje na górę stosu, ta technika polega na zastąpieniu EIP (Wskaźnik instrukcji) adresem instrukcji jmp esp
lub call esp
. Dzięki temu shellcode jest umieszczany bezpośrednio po nadpisanej wartości EIP. Gdy instrukcja ret
zostanie wykonana, ESP wskazuje na następny adres, dokładnie tam, gdzie przechowywany jest shellcode.
Jeśli Randomizacja Układu Przestrzeni Adresowej (ASLR) nie jest włączona w systemie Windows lub Linux, można użyć instrukcji jmp esp
lub call esp
znalezionych w bibliotekach współdzielonych. Jednakże, przy aktywnym ASLR, konieczne może być poszukiwanie tych instrukcji w samym programie podatnym (i być może trzeba będzie pokonać PIE).
Co więcej, umożliwienie umieszczenia shellcode po nadpisaniu EIP, a nie w środku stosu, zapewnia, że żadne instrukcje push
lub pop
wykonane podczas działania funkcji nie będą ingerować w shellcode. Taka ingerencja mogłaby wystąpić, gdyby shellcode został umieszczony w środku stosu funkcji.
Jeśli brakuje miejsca do zapisania po nadpisaniu RIP (może to być tylko kilka bajtów), napisz początkowy jmp
shellcode, na przykład:
I zapisz shellcode na początku stosu.
Możesz znaleźć przykład tej techniki w https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp z końcowym exploit'em jak:
Możesz zobaczyć kolejny przykład tej techniki na https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html. Istnieje tu przepełnienie bufora bez włączonego NX, używany jest gadżet do zmniejszenia adresu $esp
a następnie jmp esp;
aby przejść do kodu powłoki:
Podobnie, jeśli znamy funkcję zwracającą adres, w którym przechowywany jest kod powłoki, możemy wykorzystać instrukcje call eax
lub jmp eax
(znane jako technika ret2eax), oferującą inną metodę wykonania naszego kodu powłoki. Podobnie jak eax, dowolny inny rejestr zawierający interesujący adres może być użyty (ret2reg).
Możesz znaleźć kilka przykładów tutaj:
strcpy
będzie przechowywane w eax
adresie bufora, w którym przechowywany jest kod powłoki i eax
nie jest nadpisywany, więc można użyć ret2eax
.
W ARM64 nie ma instrukcji pozwalających na skok do rejestru SP. Możliwe jest znalezienie gadżetu, który przenosi sp do rejestru, a następnie skacze do tego rejestru, ale w bibliotece libc mojego kali nie znalazłem takiego gadżetu:
Jedynymi, które odkryłem, zmieniłyby wartość rejestru, do którego został skopiowany sp przed skokiem do niego (co sprawiłoby, że stałby się bezużyteczny):
Jeśli rejestr ma interesujący adres, można do niego skoczyć, znajdując odpowiednią instrukcję. Możesz użyć czegoś w stylu:
W ARM64 to x0
przechowuje wartość zwracaną przez funkcję, więc może się zdarzyć, że x0 przechowuje adres bufora kontrolowanego przez użytkownika z shellcodem do wykonania.
Przykładowy kod:
Sprawdzając rozkład funkcji, można zauważyć, że adres bufora (podatnego na przepełnienie buforu i kontrolowanego przez użytkownika) jest przechowywany w x0
przed powrotem z przepełnienia buforu:
Można również znaleźć gadżet br x0
w funkcji do_stuff
:
Wykorzystamy ten gadżet, aby do niego przeskoczyć, ponieważ binarny plik jest kompilowany BEZ PIE. Korzystając z wzorca, można zauważyć, że przesunięcie przepełnienia buforu wynosi 80, więc exploit będzie:
Jeśli zamiast fgets
zostało użyte coś w stylu read
, byłoby możliwe obejście PIE również przez nadpisanie tylko ostatnich 2 bajtów adresu powrotu aby powrócić do instrukcji br x0;
bez konieczności znajomości pełnego adresu.
Z fgets
to nie działa, ponieważ dodaje bajt null (0x00) na końcu.
NX: Jeśli stos nie jest wykonawczy, to nie pomoże, ponieważ musimy umieścić shellcode na stosie i skoczyć, aby go wykonać.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)