Poprawa czytelności dzięki adnotacjom

https://chacker.pl/

Dla początkujących bardzo frustrującą i uciążliwą częścią inżynierii odwrotnej jest brak jasnego pojęcia, co oznaczają różne parametry i wartości danych. Ten brak kontekstu w zakresie różnych ustawień wartości rejestrów, przesunięć pamięci, odwołań do wskaźników i argumentów funkcji można przezwyciężyć poprzez właściwe użycie typów danych. Jak być może już wiesz, środowisko wykonawcze architektur komputerów jest niezależne od typów danych, które są istotne dla twórcy oprogramowania w czasie programowania i są wykorzystywane przez kompilator do prawidłowego przypisywania alokacji pamięci, przesunięć elementów struktury, indeksów tablic i innych ustawień w czasie kompilacji. Jeśli porównamy oryginalny kod z domyślnym widokiem dekompilacji dla funkcji LoadStudents, pokazanym poniżej, funkcja dekompilacji może nie okazać się tak przydatna, jak to tylko możliwe. Będziemy kontynuować poprawę czytelności programu studentów poprzez przypisanie typów danych do wartości w funkcji main.

Kod źródłowy przedstawia pętlę for zwiększającą zmienną licznika o 1 w każdej iteracji, która jest używana jako indeks dla zmiennej globalnej studentów, która jest tablicą zdefiniowanego przez nas typu Student. Przed adnotacją zdekompilowana reprezentacja odpowiedniego kodu asemblera w języku C pokaże zmienną licznika indeksu pomnożoną przez 0x20 (co jest rozmiarem danych Ucznia). Ponadto, biorąc pod uwagę, że dekompilator nadal nie jest świadomy typów danych dla każdej zmiennej, każde odwołanie do wartości zostanie poddane rzutowaniu typu, co jeszcze bardziej komplikuje czytelność kodu źródłowego. Możemy łatwo poprawić czytelność, ustawiając zmienne z poprawnymi adnotacjami typu danych i zmieniając nazwy zmiennych. Załóżmy, że nie mamy kodu źródłowego, abyśmy mogli doświadczyć najczęstszego scenariusza, jakiego można się spodziewać podczas prawdziwej inżynierii odwrotnej. Wykonaj następujące kroki:

  1. Przejdź do funkcji LoadStudents, wyszukując ją w widoku drzewa symboli, a następnie przejdź do okna Dekompilacja, aby wprowadzić adnotacje. Zmienimy nazwy zmiennych, typy danych i sygnatury funkcji w oparciu o operacje i funkcje, z którymi są powiązane w kodzie.
  2. Bazując na sposobie wyłuskiwania zmiennej i ustawianiu jej z przesunięciem wynoszącym 32 (0x20) pomnożonym przez zmienną indeksującą liczbę, wiemy, że jest to tablica. Ustawione są niektóre wartości w pobliżu przesunięcia, jak pokazano poniżej:

  • W linii 25. wartość całkowita jest dereferowana w odległości 24 (0x18) bajtów od przesunięcia (liczba * 32), więc można bezpiecznie założyć, że jest to wskaźnik do wartości całkowitej (int *). Nazwa powinna brzmieć „id”, ponieważ jest ustawiana ze zmiennej indeksowej licznika.
  • W linii 26. funkcja strncpy kopiuje ciąg znaków odpowiadający nazwisku ucznia odczytanemu z pliku CSV do przesunięcia bazowego (liczba * 32), więc jest to tablica znaków o nieznanym rozmiarze. Możemy jednak zgadnąć, że są to 24 bajty, ponieważ to tam znajduje się przesunięcie poprzedniej wartości i nie powinno ono nadpisywać elementu własnej struktury (char [24]). Nazwiemy ten element struktury „imięm”.
  • W linii 28. iVar1 jest ustawiany za pomocą funkcji atoi wywoływanej na podstawie wartości ocen w pliku CSV, która zwraca liczbę całkowitą, a następnie ustawiany jest z przesunięciem 0x1c od przesunięcia bazowego (liczba * 32). Załóżmy zatem, że jest to również liczba całkowita. Jest to członek „klasy” struktury ucznia.
  1. Teraz możemy zdefiniować własny typ danych struktury Studenta dla elementów tablicy studentów. Przejdź do okna Menedżer typów danych, kliknij prawym przyciskiem myszy typy danych programu „studenckiego”, wybierz podmenu Nowy i kliknij element „struktura”.
  2. Nazwij strukturę Student i ustaw jej rozmiar na 32 bajty.
  3. Przejdź do pierwszego wiersza w tabeli (offset 0), kliknij dwukrotnie DataType

pole i wpisz char[24]. Następnie kliknij dwukrotnie pole Nazwa i wpisz nazwę.

  1. W drugim wierszu (przesunięcie 24) ustaw pole DataType na int i ustaw pole Name na id.
  2. Powtórz to samo w trzecim wierszu (przesunięcie 28) i ustaw pole Nazwa na oceny.
  3. Jeśli okno Edytora struktury wygląda jak to na rysunku , kliknij ikonę Zapisz i zamknij okno. Konstrukcja jest już gotowa do użycia.

  1. Umieść kursor nad dowolną instancją zmiennej globalnej studentów i naciśnij CTRL-L, aby zmienić jej typ danych z niezdefiniowany[1024] na Student[32] (nasza struktura ma rozmiar 32, a 1024 podzielone przez 32 równa się 32) .
  2. Zmień pozostałe zmienne i funkcje w oparciu o ich kontekst. Na przykład zmienna local_20 jest ustawiana w wyniku funkcji fopen; dlatego powinien być ustawiony jako typ danych FILE *, a jego nazwa powinna wyglądać mniej więcej tak: fh.
  3. Naciśnij CTRL-L, aby zmienić jego typ na PLIK *.
  4. Wybierz nazwę zmiennej i naciśnij L lub kliknij prawym przyciskiem myszy i wybierz

Zmień nazwę zmiennej, aby zmienić nazwę zmiennej na fh.

C. Aby uniknąć rzutowania wywołania na fopen, kliknij funkcję prawym przyciskiem myszy, kliknij opcję Edytuj sygnaturę funkcji i, jeśli to konieczne, zmień sygnaturę funkcji, aby ustawić poprawny argument wywołania i zwrócić typy danych.

Jeśli nie masz pewności co do sygnatury standardowych funkcji, skorzystaj z podręcznika programisty, uruchamiając man 3 fopen w oknie terminala. Po zakończeniu tego procesu powinieneś zauważyć, że czytelność zarówno zdekompilowanego, jak i wyszczególniającego zdezasemblowany kod została znacznie poprawiona, jak pokazano poniżej. Ponadto każda inna funkcja odwołująca się do zmiennych, funkcji i typów danych z adnotacjami odniesie korzyści z tego wysiłku

Wykresy

https://chacker.pl/

Ghidra zapewnia zaawansowane funkcje generowania wykresów. Czasami przebieg wykonywania i warunki warunkowe mogą stać się nieuporządkowane, a bez wykresów zrozumienie kodu może wydawać się zadaniem niemożliwym. Wykresy składają się z wierzchołków (lub bloków) i krawędzi (lub przepływu sterowania) i mogą pomóc w zrozumieniu rozgałęzień, przepływu sterowania, pętli, odniesień, a nawet korelacji między funkcjami i etykietami w programie.

Istnieją dwa typy wykresów:

  • Wykresy przepływu Wyświetlają przepływ (przeskoki przelotowe i bezwarunkowe) pomiędzy wybranymi blokami kodu.
  • Wykresy połączeń Wyświetla sekwencję wywołań pomiędzy funkcjami.

Możesz wygenerować wykres wybranego kodu lub funkcji, przechodząc do menu Wykres i wybierając żądany wykres. Menu Wykres udostępnia następujące narzędzia:

  1. Pasek narzędzi Umożliwia szybki dostęp do ustawień i odświeżania wyświetlania wykresów oraz innych opcji.
  2. Widok wykresu Wyświetlane są tutaj wszystkie bloki (wierzchołki) i przepływ (krawędzie), co ułatwia nawigację, grupowanie i kontrolę. Można przesuwać, przeciągając myszą, a także przybliżać i oddalać za pomocą kółka myszy lub gładzika.

3. Widok satelitarny Pomaga szybko poruszać się po wykresie, pokazując małą mapę wszystkich przedstawionych na wykresie bloków.

Możesz także eksportować wykresy do wielu formatów graficznych i danych, takich jak CSV, DOT, GML, JSON, Visio i inne.

Adnotacje programu

https://chacker.pl/

Adnotacje pomagają poprawić czytelność, zapewniają wyjaśnienia i śledzą pracę wykonaną nad odwróconym programem. Adnotacje wpływają również na wynikowy wynik dekompilatora. Ghidra udostępnia wiele rodzajów adnotacji. Oto niektóre z najważniejszych:

  • Możesz używać specjalnych adnotacji w komentarzach jako ciągów formatujących. Wpływają one na wynikowy wynik, określając wartości jako adresy łańcuchowe, symbole, adresy URL i inne formaty.
  • Adnotacje zmiennych umożliwiają zmianę nazwy symbolu zmiennej, jej typu danych i lokalizacji przechowywania.
  • Zmiana nazwy etykiety umożliwia zmianę nazwy etykiety i wywnioskowanych nazw na bardziej szczegółowe w celu lepszego zrozumienia kodu.

• Adnotacji funkcji można używać do zmiany nazwy funkcji, podpisu, konwencji wywoływania i typu danych wartości zwracanej.

Dekompilator

https://chacker.pl/

Funkcja Decompile zapewnia reprezentację zdezasemblowanego kodu w języku C, jak pokazano poniżej:

Chociaż skompilowanego kodu binarnego nie można przywrócić do źródła, dekompilator zapewnia dobrą rekonstrukcję logiki wyrażonej przez kod programu. Ta funkcja jest bardzo przydatna zarówno dla początkujących, jak i doświadczonych inżynierów wstecznych, ponieważ zmniejsza złożoność i poprawia czytelność programu.

Szukaj

https://chacker.pl/

Ghidra zapewnia funkcję wyszukiwania, która umożliwia wyszukiwanie określonych wzorców binarnych, tekstu w kodzie programu, symboli, nazw funkcji, komentarzy i innych. Oferuje także inteligentne wyszukiwanie określonych wzorców instrukcji, skalarów i ciągów znaków (niezależnie od ich kodowania)

Przeglądarka kodów

https://chacker.pl/

Przeglądarka kodów zapewnia intuicyjny interfejs użytkownika do podstawowych funkcjonalności i nawigacji Ghidry. Większość czasu spędzonego na pracy z Ghidrą spędzisz w tym widoku, ponieważ zawiera on menu i paski narzędzi do najpopularniejszych zadań. Domyślny układ pokazano na rysunku  i opisano w dalszej części.

(1) Menu główne W tym menu dostępne są wszystkie główne opcje.

(2) Pasek narzędzi Tutaj znajdziesz grupę ikon przycisków, których możesz używać jako skrótów do typowych funkcji.

(3) Drzewa programów Zawiera listę drzewiastą wszystkich segmentów pamięci zdefiniowanych przez plik binarny i będzie się różnić w zależności od formatu binarnego i programu ładującego.

(4) Drzewo symboli Tutaj możesz szybko poruszać się po wszystkich symbolach zdefiniowanych w informacjach debugowania lub rozwiązanych przez wstępną analizę. Symbole te są oddzielone typem: import, eksport, funkcje, etykiety, klasy i przestrzenie nazw

(5) Menedżer typów danych Wbudowane, ogólne, dostarczane binarnie i zdefiniowane przez użytkownika typy danych będą dostępne tutaj. Możesz łatwo przechodzić do operacji na wartościach i referencjach według ich typu danych.

(6) Listing Tutaj wymieniono dezasemblację kodu programu i odniesienia do danych. Możesz łatwo eksplorować logikę programu, odniesienia i przesunięcia adresów. Wyświetlane są tutaj również specjalne komentarze i nazwane wartości wygenerowane przez moduł ładujący i analizator Ghidra.

(7) Dekompiluj To okno wyświetla reprezentację funkcji wybranej w oknie Listing w języku C. Ta dekompilacja ułatwia proces analizowania dużych i złożonych bloków kodu asemblera.

(8) Konsola – Skrypty Tutaj pokazane są wyniki i dane wyjściowe skryptów i wtyczek.

Jeśli przejdziesz do Drzew programów i klikniesz dwukrotnie segment pamięci .text, okno Listing przejdzie na początek kodu wykonywalnego programu i wyświetli kod deasemblujący wzbogacony o zmianę nazwy i komentarze powstałe w wyniku poprzedniej analizy. Zawiera także intuicyjne informacje umożliwiające eksplorację i zrozumienie kodu, takie jak adresowanie, kod bajtowy instrukcji, operandy danych z komentarzami, etykiety, informacje o przepływie rozgałęzień warunkowych i odniesienia.

W drzewie symboli przejdź do pola Filtruj tekst i wpisz LoadStudents, aby wyszukać tę funkcję. Kliknij, aby wyświetlić funkcję w oknie Lista:

Okno Listing posiada wzbogacony widok zdezasemblowanego kodu programu:

(1) Pasek narzędzi Listing zapewnia szybki dostęp do funkcji kopiowania i wklejania, podglądu podpowiedzi, edytora pól list, widoku różnic dla porównań programów, migawek i przełączania wyświetlania marginesów. Możesz kliknąć przycisk Edytuj pola aukcji na pasku narzędzi, aby dostosować domyślny układ aukcji.

(2) Komentarze ułatwiają śledzenie Twojej pracy. Czasami są one dostarczane w wyniku analizy wartości i argumentów różnych symboli, ale możesz dodać własne, naciskając ; (średnik) lub klikając prawym przyciskiem myszy wybrany adres i przechodząc do wyskakującego menu Komentarze.

(3) Strzałki przepływu pokazują miejsce docelowe skoków warunkowych i bezwarunkowych.

(4) Linki odsyłające dostarczają informacji o tym, gdzie w programie wartości są odczytywane i zapisywane oraz gdzie wywoływane są funkcje lub do których odwołują się. Dwukrotne kliknięcie tych linków przeniesie widok Listy na wskazany adres. Odniesienia można także znaleźć pod dowolnym adresem lub symbolem, naciskając klawisze CTRL-SHIFT-F.

(5) Adres pamięci pokazuje bezwzględne odniesienie numeryczne do dowolnego kodu lub wartości przeglądanej w oknie Lista. Możesz przejść do dowolnego adresu w otwartym pliku, naciskając G.

(6) Bajty kodu to binarna reprezentacja bieżącej instrukcji zakodowana w formacie szesnastkowym.

(7) Kod demontażu to miejsce, w którym znajdują się zdezasemblowane i przeanalizowane instrukcje wraz z ich mnemonikami i argumentami. Możesz poprawiać i zmieniać te instrukcje, naciskając CTRL-SHIFT-G.

(8) Paski boczne Legenda Entropii i Legenda przeglądu pomagają szybko przeglądać i poruszać się po różnych częściach programu poprzez kodowanie kolorami w skali szarości binarnej wariancji i kodowanie entropii oraz poprzez udostępnianie bloków oznaczonych jako Funkcja, Niezainicjowane, Odniesienie zewnętrzne, Instrukcja, Dane i Niezdefiniowane . Odniesienia oznaczone kolorami można wyświetlić, klikając prawym przyciskiem myszy pasek boczny i wybierając opcję Pokaż legendę.

Przegląd funkcjonalności

https://chacker.pl/

Chociaż Ghidra oferuje wiele funkcji i funkcjonalności, dla uproszczenia skupimy się tylko na najbardziej podstawowych i korzystnych funkcjach.

Okno projektu

Okno projektu jest głównym oknem dostępnym po załadowaniu Ghidry; zapewnia funkcje zarządzania projektami, pliki docelowe aktywnego projektu, skrzynki narzędziowe i ogólną definicję obszaru roboczego. Stwórzmy nasz projekt i rozpocznijmy pracę z wcześniej skompilowanymi plikami docelowymi. Uruchom Ghidrę, jeśli jeszcze tego nie zrobiłeś, a następnie wykonaj następujące kroki:

  1. Utwórz nowy projekt klikając Plik | Nowy lub naciskając CTRL-N. Ustawimy ten projekt jako prywatny (czyli projekt niewspółdzielony), a także ustalimy nazwę projektu i folder, w którym będzie się on znajdować.
  2. Dołącz ucznia i pliki binarne z poprawkami do projektu, klikając Plik | Importuj lub naciskając I dla każdego z nich. Spowoduje to wykrycie formatu i języka pliku binarnego (w tym przypadku ELF skompilowany z x86:LE:64:default:gcc), jak pokazano poniżej.

  1. Kliknij przycisk OK. Zostanie wyświetlone podsumowanie wyników importu z metadanymi pliku i właściwościami nagłówka.
  2. Kliknij dwukrotnie plik docelowy uczniów, aby uruchomić przeglądarkę kodów i rozpocząć analizę.

Analiza

Gdy tylko Ghidra załaduje program, sugeruje analizę programu, jeśli nie zostało to już wcześniej zrobione:

Analizator wykonuje wiele zadań, ale najważniejsze z nich zostały pokazane tutaj i opisane poniżej:

  • Analizator funkcji Przypisuje adresy i nazwy funkcjom na podstawie ich symboli lub poprzez wykrywanie prologów i epilogów funkcji podczas deasemblacji kodu.
  • Analizator stosu Wnioskuje o rozmiarach zmiennych stosu i odniesieniach w oparciu o operacje na podstawie stosu i wskaźniku na początku funkcji.
  • Analizator argumentów Przypisuje i rozwiązuje odniesienia do adresów i symboli w oparciu o operandy skalarne.
  • Analizator odwołań do danych Rozpoznaje adresy i odniesienia do wartości danych i oczywistych typów danych w oparciu o lokalizację sekcji pamięci i argumenty w kodzie.

Analiza | Podmenu One-Shot umożliwia uruchomienie wielu lub wszystkich różnych zadań analitycznych na wybranym bloku kodu.

Ustawianie obszaru roboczego projektu

https://chacker.pl/

Pierwszą rzeczą, którą zobaczysz po uruchomieniu Ghidry, jest okno projektu i wyskakujące okienko „Wskazówka dnia” (które zalecamy sprawdzać od czasu do czasu). Możesz zamknąć to wyskakujące okienko, aby wyświetlić okno projektu. W oknie projektu możesz zarządzać swoimi projektami, obszarem roboczym i narzędziami. Domyślnie Ghidra jest dostarczana z przeglądarką kodu i narzędziami do śledzenia wersji. Pod koniec przeprowadzimy Cię przez proces instalacji narzędzia Debugger.

Instalacja i Szybki Start

https://chacker.pl/

Zacznijmy od zainstalowania zależności wykonawczej Java 11 dla Ghidry w domyślnym systemie Kali:

Następnie pobierz pakiet wersji v9.2.3 Ghidry z oficjalnej strony internetowej Ghidra (https://ghidra-sre.org) i rozpakuj go do swojego katalogu domowego:

Następnie pobierz pakiet wersji v9.2.3 Ghidry z oficjalnej strony internetowej Ghidra (https://ghidra-sre.org) i rozpakuj go do swojego katalogu domowego:

Powinno to uruchomić Ghidrę po raz pierwszy i wyświetlić umowę użytkownika końcowego.

Tworzenie naszego pierwszego projektu

https://chacker.pl/

Skompilujemy przykładowy program odpowiedni do zaprezentowania cech i funkcjonalności Ghidry. Ten przykładowy program to narzędzie do zarządzania ocenami uczniów, które ładuje plik CSV i zawiera lukę w zabezpieczeniach naszych zadań związanych z analizą praktyczną. Udostępniane są pliki studenci.c, studenci-patched.c i studenci.csv w folderze ~/GHHv6/ch04, pod warunkiem, że wcześniej sklonowałeś repozytorium Git Gray Hat Hacking 6th Edition. Uruchom następujące polecenia w oknie terminala, aby skompilować dwie wersje programu (domyślną wersję zawierającą lukę i wersję poprawioną):

Teraz, gdy mamy gotowe programy docelowe, możemy stworzyć projekt do pracy z nimi i zapoznać się z funkcjami i funkcjonalnością Ghidry.