Ret2csu
https://www.scs.stanford.edu/brop/bittau-brop.pdfPodstawowe informacje
ret2csu to technika hakowania stosowana, gdy próbujesz przejąć kontrolę nad programem, ale nie możesz znaleźć gadżetów, których zwykle używasz do manipulowania zachowaniem programu.
Gdy program korzysta z pewnych bibliotek (np. libc), ma wbudowane funkcje do zarządzania tym, jak różne części programu rozmawiają ze sobą. Wśród tych funkcji są ukryte perełki, które mogą działać jako nasze brakujące gadżety, zwłaszcza jedna o nazwie __libc_csu_init
.
Magiczne gadżety w __libc_csu_init
W __libc_csu_init
znajdują się dwie sekwencje instrukcji (gadżetów), które warto podkreślić:
Pierwsza sekwencja pozwala nam ustawić wartości w kilku rejestrach (rbx, rbp, r12, r13, r14, r15). Są to miejsca, w których możemy przechowywać liczby lub adresy, których chcemy użyć później.
Ten gadżet pozwala nam kontrolować te rejestry, wypychając wartości ze stosu do nich.
Druga sekwencja wykorzystuje ustawione przez nas wartości do wykonania kilku czynności:
Przenosi konkretne wartości do innych rejestrów, przygotowując je do użycia jako parametry w funkcjach.
Wykonuje wywołanie do lokalizacji określonej przez dodanie do siebie wartości w r15 i rbx, a następnie pomnożenie rbx przez 8.
Być może nie znasz żadnego adresu do zapisania tam i potrzebujesz instrukcji
ret
. Zauważ, że drugi gadżet również kończy się naret
, ale będziesz musiał spełnić pewne warunki, aby go osiągnąć:
Warunki będą następujące:
[r12 + rbx*8]
musi wskazywać na adres przechowujący funkcję wywoływalną (jeśli nie masz pomysłu i nie ma ASLR, możesz po prostu użyć funkcji_init
):Jeśli _init znajduje się pod adresem
0x400560
, użyj GEF, aby wyszukać wskaźnik w pamięci do niego i spraw, aby[r12 + rbx*8]
był adresem z wskaźnikiem do _init:
rbp
irbx
muszą mieć tę samą wartość, aby uniknąć skokuIstnieją pewne pominięte operacje
pop
, które trzeba wziąć pod uwagę
RDI i RSI
Innym sposobem na kontrolowanie rdi
i rsi
z gadżetu ret2csu jest dostęp do konkretnych przesunięć:
Sprawdź tę stronę, aby uzyskać więcej informacji:
pageBROP - Blind Return Oriented ProgrammingPrzykład
Użycie wywołania
Wyobraź sobie, że chcesz wykonać wywołanie systemowe lub wywołać funkcję taką jak write()
, ale potrzebujesz określonych wartości w rejestrach rdx
i rsi
jako parametry. Zazwyczaj szukałbyś gadżetów, które ustawiają te rejestry bezpośrednio, ale nie możesz ich znaleźć.
Tu właśnie przychodzi z pomocą ret2csu:
Ustaw Rejestry: Użyj pierwszego magicznego gadżetu, aby zdjąć wartości ze stosu i umieścić je w rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) i r15.
Użyj Drugiego Gadżetu: Mając te rejestry ustawione, używasz drugiego gadżetu. Pozwala to przenieść wybrane wartości do
rdx
irsi
(odpowiednio z r14 i r13), przygotowując parametry do wywołania funkcji. Ponadto, kontrolującr15
irbx
, możesz sprawić, że program wywoła funkcję znajdującą się pod adresem, który obliczasz i umieszczasz w[r15 + rbx*8]
.
Masz przykład użycia tej techniki i jej wyjaśnienie tutaj, a to jest ostateczny exploit, który został użyty:
Należy zauważyć, że poprzednie wykorzystanie nie ma na celu wykonania RCE
, ma ono na celu jedynie wywołanie funkcji o nazwie win
(pobierając adres win
ze standardowego wejścia za pomocą wywołania gets w łańcuchu ROP i przechowując go w r15) z trzecim argumentem o wartości 0xdeadbeefcafed00d
.
Ominięcie wywołania i dotarcie do ret
Następujące wykorzystanie zostało wyodrębnione z tej strony, gdzie używane jest ret2csu, ale zamiast używać wywołania, omija porównania i dociera do ret
po wywołaniu:
Dlaczego nie używać libc bezpośrednio?
Zazwyczaj te przypadki są również podatne na ret2plt + ret2lib, ale czasami potrzebujesz kontrolować więcej parametrów niż łatwo jest to zrobić za pomocą gadżetów znalezionych bezpośrednio w libc. Na przykład funkcja write()
wymaga trzech parametrów, a znalezienie gadżetów do ustawienia wszystkich tych parametrów bezpośrednio może być niemożliwe.
Last updated