Inżynieria wsteczna, część 1 — analiza statyczna¶
Data: 05.11.2020, 10.11.2020
Treść
Narzędzia¶
GHIDRA: https://ghidra-sre.org/ (otwarty disassembler i dekompilator)
Python 3
Obsługa programu GHIDRA¶
Tworzymy nowy projekt
Importujemy program binarny (przycisk
I
)Otwieramy program binarny (podwójnym kliknięciem na plik w liście plików)
Uruchamiamy automatyczną analizę (domyślne ustawienia powinny działać) i czekamy na zakończenie
Przeglądamy kod, poprawiamy błędnie wywnioskowane informacje, dodajemy typy danych, nazywamy funkcje, …
Najważniejsze funkcje programu GHIDRA:
zmiana nazwy, parametrów i typu zwracanego funkcji: klikamy w nazwę funkcji w panelu disassemblera (pierwsze wystąpienie nazwy — drugie nie działa) i naciskamy
F
zmiana typu zmiennej lokalnej: klikamy w nazwę zmiennej lokalnej w panelu dekompilacji, naciskamy
Ctrl-L
zmiana nazwy zmiennej lokalnej: jak wyżej, naciskamy
L
Przykład 1: proste porównanie¶
Program: simple
Zadanie: znaleźć poprawne hasło do programu.
Jest kilka sposobów rozwiązania zadania:
Ładujemy do programu GHIDRA, czytamy funkcję
main
Używamy polecenia
strings
i po prostu znajdujemy hasło
Źródło: simple.c
Przykład 2: prosty szyfr¶
Program: encrypted
Zadanie: znaleźć poprawne hasło do programu.
Ładujemy do programu GHIDRA
Czytamy funkcję
main
, widzimy że właściwe sprawdzenie następuje znak po znaku w funkcjicheck
Czytamy i odwracamy funkcję
check
Źródło: encrypted.c
Przykład 3: obliczenia¶
Program: key_checker
Zadanie: znaleźć poprawne hasło do programu.
Ładujemy do programu GHIDRA
Program nie ma symboli — znajdujemy i oznaczamy funkcję
main
przez popatrzenie na punkt wejścia programu i wzięcie pierwszego parametru do__libc_start_main
Zmieniamy nazwę zmiennej, do której
scanf
wczytuje hasło i poprawiamy jej typ nachar[64]
(GHIDRA nie radzie sobie z wykryciem rozmiaru sama)Widzimy wywołania do trzech podfunkcji — pierwsza jest oczywista, druga wymaga odrobiny ręcznej analizy
W trzeciej podfunkcji widzimy, że wartość zwracana nie ma sensu — poprawiamy to, ustawiając typ zwracany na
bool
Pierwsze dwie funkcje odwracamy ręcznie, do odwrócenia trzeciej używamy np. Pythona 3 z bilbioteką
gmpy2
:import gmpy2 print(int((gmpy2.invert(0x7b, 2**64) * -0x34306269e095bb9a) % 2 ** 64).to_bytes(8, 'little'))