BF Addresses in the Stack
Jeśli masz do czynienia z binarnym plikiem chronionym przez canary i PIE (Position Independent Executable), prawdopodobnie będziesz musiał znaleźć sposób na ich obejście.
Zauważ, że checksec
może nie wykryć, że binarny plik jest chroniony przez canary, jeśli został on skompilowany statycznie i nie jest w stanie zidentyfikować funkcji.
Jednakże, możesz zauważyć to ręcznie, jeśli zauważysz, że wartość jest zapisywana na stosie na początku wywołania funkcji, a następnie sprawdzana przed wyjściem.
Adresy BF (Brute-Force)
Aby obejść PIE, musisz wyciec pewien adres. Jeśli binarny plik nie wycieka żadnych adresów, najlepiej jest przeprowadzić atak siłowy na RBP i RIP zapisane na stosie w podatnej funkcji. Na przykład, jeśli binarny plik jest chroniony zarówno przez canary, jak i PIE, możesz zacząć atak siłowy od canary, a następnie następne 8 bajtów (x64) będą zapisane jako RBP, a kolejne 8 bajtów będą zapisane jako RIP.
Zakłada się, że adres powrotu na stosie należy do kodu binarnego głównego, co w przypadku, gdy podatność znajduje się w kodzie binarnym, zazwyczaj będzie prawdą.
Aby przeprowadzić atak siłowy na RBP i RIP z binarnego pliku, możesz ustalić, że poprawny zgadnięty bajt jest poprawny, jeśli program coś wypisze lub po prostu nie ulegnie awarii. Ta sama funkcja, co ta używana do ataku siłowego na canary, może być użyta do ataku siłowego na RBP i RIP:
Ostatnią rzeczą, którą musisz zrobić, aby pokonać PIE, jest obliczenie użytecznych adresów z wyciekłych adresów: RBP i RIP.
Z RBP możesz obliczyć gdzie zapisujesz swój shell na stosie. Może to być bardzo przydatne, aby wiedzieć, gdzie zamierzasz zapisać ciąg "/bin/sh\x00" wewnątrz stosu. Aby obliczyć odległość między wyciekiem RBP a swoim kodem shell, wystarczy ustawić punkt przerwania po wycieku RBP i sprawdzić gdzie znajduje się twój kod shell, a następnie obliczyć odległość między kodem shell a RBP:
Z RIP można obliczyć adres bazowy binarnego PIE, który będzie potrzebny do utworzenia poprawnego łańcucha ROP.
Aby obliczyć adres bazowy, wykonaj objdump -d vunbinary
i sprawdź ostatnie adresy rozkładu:
W tym przykładzie widać, że potrzebny jest tylko 1 bajt i pół, aby zlokalizować cały kod, więc adres bazowy w tej sytuacji będzie wyciekły RIP, ale kończący się na "000". Na przykład, jeśli wyciekł 0x562002970ecf
, adres bazowy to 0x562002970000
Poprawki
Zgodnie z pewnymi obserwacjami z tego posta, możliwe jest, że wyciekając wartości RBP i RIP, serwer nie ulegnie awarii przy niektórych wartościach, które nie są poprawne, a skrypt BF będzie myślał, że otrzymał te właściwe. Dzieje się tak dlatego, że możliwe jest, że niektóre adresy po prostu nie spowodują awarii, nawet jeśli nie są to dokładnie te poprawne.
Zgodnie z tym postem zaleca się dodanie krótkiego opóźnienia między żądaniami wysyłanymi do serwera.
Last updated