Framework i exploit Pwntools CTF

https://chacker.pl/

Biblioteka Rozwoju

Pwntools to biblioteka do przechwytywania flagi (CTF) i programowania exploitów, która doskonale nadaje się do szybkiego prototypowania exploitów. Oszczędza dużo czasu i wysiłku podczas pisania typowych zadań związanych z eksploatacją, pozwala skupić się na logice exploita, a także zapewnia szeroki zestaw przydatnych funkcji. Wykonaj następujące polecenia, aby zainstalować pwntools:

Rozszerzanie gdb za pomocą Pythona

https://chacker.pl/

W wersji 7 dodano obsługę rozszerzania gdb za pomocą Pythona. Ta funkcja jest dostępna tylko wtedy, gdy gdb został skompilowany z opcją konfiguracyjną –withpython. Dzięki tej funkcji, poza możliwością pisania niestandardowych funkcji i automatyzacji wielu zadań, aktywnie rozwijano wiele projektów wtyczek gdb w celu uproszczenia i wzbogacenia procesu debugowania o takie funkcje, jak osadzony widok zrzutu szesnastkowego, wyłuskiwanie danych lub rejestrów, sterta analiza, automatyczne wykrywanie stanu bez użycia (UAF) i inne zaawansowane funkcje. Oto niektóre z najpopularniejszych skryptów gdb:

  1. Ulepszone funkcje Gef9 GDB dla twórców exploitów i inżynierów wstecznych
  2. Pwndbg10 Tworzenie exploitów i inżynieria wsteczna dzięki GDB Made Easy

3. PEDA11 Pomoc w opracowywaniu exploitów w języku Python dla GDB.

Ropper

https://chacker.pl/

Ropper to przydatne narzędzie do generowania łańcuchów ROP i znajdowania gadżetów do ponownego wykorzystania kodu. Jest w stanie ładować pliki binarne w formatach ELF, PE i Mach-O i obsługuje wiele architektur (x86, x86_64, MIPS, MIPS64, ARM/Thumb, ARM64, PowerPC i Sparc) przy użyciu platformy deasemblacji Capstone7. Aby zainstalować Roppera, użyj sudo apt install ropper. Jedną z jego najciekawszych funkcji jest możliwość wyszukiwania gadżetów na podstawie ograniczeń i warunków formatu pliku. Utwórzmy łańcuch ROP, który wywoła mprotect(), aby włączyć uprawnienia wykonywalne dla dowolnego adresu

Powstały fragment kodu Pythona zostanie utworzony:

Możemy również użyć wyszukiwania semantycznego, aby znaleźć gadżet, który zwiększa wskaźnik stosu o 16 bajtów, unikając zaśmiecania rejestrów R15 i RDI: ropper — plik <plik-binarny> –semantic „rsp+=16 !r15 !rdi”. Aby skorzystać z tej funkcji, musisz zainstalować pyvex i z3, postępując zgodnie z instrukcjami na stronie projektu GitHub. Jak widać, oszczędza to dużo czasu i wysiłku, a także zapewnia wiele innych interesujących funkcji — od programowania zorientowanego na skok (JOP) po obracanie stosu.

Korzystanie z narzędzia one_gadget

https://chacker.pl/

Zamiast ręcznie szukać one_gadgets dla wielu wersji glibc, możesz użyć narzędzia one_gadget, napisanego w języku Ruby przez david942j i dostępnego w RubyGems (gem install one_gadget). To narzędzie wykorzystuje wykonanie symboliczne do znalezienia one_gadgets i ich ograniczeń. Projekt ten jest dostępny na GitHubie.6 Aby go zainstalować, użyj polecenia sudo gem install one_gadget. Aby automatycznie znaleźć one_gadgets, uruchamiamy narzędzie, podając bibliotekę docelową w następujący sposób:

one_gadget

https://chacker.pl/

One_gadgets znajdują się w bibliotece libc i zapewniają prosty sposób uzyskania powłoki poprzez przeskoczenie do pojedynczego gadżetu w celu wykonania execve(„/bin/sh”, NULL, NULL). Te magiczne gadżety możemy znaleźć na dwa sposoby: ręcznie za pomocą ciągów znaków i objdump lub za pomocą narzędzia one_gadget.

Ręczne użycie ciągów i objdump

Najpierw użyjmy ciągów znaków, aby uzyskać adres przesunięcia /bin/sh w docelowej bibliotece libc:

Następnie możemy użyć objdump do wyszukania odniesień do adresu ciągu /bin/sh:

Jedynym ograniczeniem jest to, że w momencie wykonania r12 i r13 muszą być równe NULL. W ten sposób rejestry rdi, rsi i rdx będą zawierać odpowiednio wartości /bin/sh, NULL, NULL.

patchel

https://chacker.pl/

Narzędzie wiersza poleceń Patchelf pozwala nam modyfikować biblioteki pliku wykonywalnego ELF. Jest to bardzo przydatne, gdy przeprowadzamy analizę sterty na innej wersji libc niż ta używana przez system zdalny lub gdy nie mamy dostępu do kodu źródłowego i chcemy uruchomić wiele wersji libc w tym samym systemie. Możesz pobrać patchelf z repozytorium GitHub5 lub po prostu zainstalować go za pomocą sudo apt install patchelf. W tym laboratorium załatamy plik binarny hello, aby korzystał z interpretera i wersji libc:

  1. Najpierw tworzymy folder lib i kopiujemy systemowe pliki ld-linux.so i libc:

  1. Teraz możemy załatać plik binarny hello i potwierdzić, że zmiany zostały wprowadzone pomyślnie i że nasz program działa:

libc-database

https://chacker.pl/

Czasami udaje ci się znaleźć i wykorzystać lukę w zabezpieczeniach pliku informacyjnego, ale nie jest możliwe obliczenie przesunięcia w stosunku do bazy libc lub innych funkcji, chyba że znasz wersję libc używaną na zdalnym hoście. Biblioteka libcdatabase pobiera listę skonfigurowanych wersji ibc, wyodrębnia przesunięcia symboli i umożliwia sprawdzenie nazwy funkcji i adresu, który wyciekł, w celu zidentyfikowania używanej wersji libc.

1. Sklonujmy repozytorium GitHub libc-database:

  1. Możliwe jest pobranie wszystkich wstępnie udostępnionych wersji libc w ramach skryptu get, ale można także pobrać wersje specyficzne dla dystrybucji dla systemów Ubuntu, Debian, RPM, CentOS, Arch, Alpine, Kali i Parrot OS. Pobierzmy wersje libc używane przez Kali Linux. W folderze /home/kali/libc-database wykonaj następujące czynności:

3. Znajdź w bazie danych wszystkie wersje libc, które mają podane nazwy pod podanymi adresami. Użyjmy readelf, aby uzyskać przesunięcie put, a następnie użyjmy skryptu find libc-database:

3. Znajdź w bazie danych wszystkie wersje libc, które mają podane nazwy pod podanymi adresami. Użyjmy readelf, aby uzyskać przesunięcie put, a następnie użyjmy skryptu find libc-database:

checksec

https://chacker.pl/

Skrypt powłoki checksec analizuje nagłówek ELF programu, aby określić, które technologie ograniczające czas kompilacji są używane, takie jak RELRO, NX, Stack Canaries, ASLR i PIE. Pomaga to zidentyfikować ograniczenia w eksploatacji. Podobne funkcje i polecenia checksec są również dostępne w większości narzędzi i struktur programistycznych (takich jak funkcja pwntools checksec). Możemy pobrać checksec bezpośrednio ze strony GitHub2 lub zainstalować go za pomocą sudo apt install checksec. Uruchomienie checksec w skompilowanym wcześniej programie hello wyświetli włączone środki zaradcze (w zależności od ustawień domyślnych konfiguracji gcc dystrybucji), jak pokazano tutaj:

Skompilujmy ponownie nasz program hello.c z włączonymi wszystkimi zabezpieczeniami, a następnie uruchommy checksec:

Śledzenie

https://chacker.pl/

Głównym celem narzędzia ltrace jest śledzenie wywołań bibliotek współdzielonych i ich odpowiedzi, ale można go również wykorzystać do śledzenia wywołań systemowych. Upewnij się, że masz zainstalowany pakiet ltrace za pomocą polecenia dpkg -l ltrace, ponieważ nie jest on domyślnie dostarczany z Kali. Użyj sudo apt install ltrace na wypadek, gdybyś musiał go zainstalować. Oto wynik działania ltrace ./hello:

UWAGA: Możesz użyć opcji -S, aby wyświetlić wywołania systemowe.

strace

https://chacker.pl/

Narzędzie wiersza poleceń strace jest przydatne, gdy musimy śledzić wywołania i sygnały systemowe. Wykorzystuje wywołanie systemowe ptrace do sprawdzania programu docelowego i manipulowania nim, a poza tym, że pozwala nam lepiej zrozumieć zachowanie programu, może być również wykorzystywane do manipulowania zachowaniem wywołań systemowych w celu lepszego rozwiązywania problemów lub szybszego odtworzenia ataku w określonych warunkach sytuacjach (na przykład wprowadzenie błędu, wprowadzenie wartości zwracanej, wprowadzenie sygnału i wprowadzenie opóźnienia). Spójrzmy na kilka przykładów. Przede wszystkim upewnij się, że masz zainstalowany pakiet strace za pomocą polecenia dpkg -l strace, ponieważ domyślnie nie jest on dostarczany z Kali. Używaj sudo apt install strace, aby go zainstalować. Kiedy uruchomisz strace bez argumentów, wyświetli wszystkie wywołania systemowe i sygnały, tak jak poniżej:

Możemy użyć opcji -e trace=syscall, jeśli chcemy prześledzić/filtrować określone wywołanie systemowe, jak pokazano poniżej:

Jak zachowałby się program, gdyby funkcja zapisu nie została zaimplementowana?

Możemy również wstrzyknąć konkretną odpowiedź na błąd. Zamiast tego wstrzyknijmy błąd „EAGAIN (Zasób tymczasowo niedostępny)”:

Możliwe jest również użycie strace do wstrzykiwania opóźnień. Jest to bardzo pomocne w wielu przypadkach, ale dobrym przykładem jest sytuacja, w której musimy uczynić warunek wyścigu bardziej deterministycznym, pomagając zmniejszyć losowość wywłaszczania programu planującego. Wprowadźmy opóźnienie 1 sekundy przed wykonaniem funkcji odczytu (delay_enter) i opóźnienie 1 sekundę po wykonaniu funkcji zapisu (delay_exit). Domyślnie oczekiwana precyzja czasu to mikrosekundy:

Jeśli chcesz dowiedzieć się więcej o strace, Dmitry Levin ( przeprowadzi Cię przez listę zaawansowanych funkcji w swoim przemówieniu „Modern strace”.