Ret2csu

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Informations de base

ret2csu est une technique de piratage utilisée lorsque vous essayez de prendre le contrôle d'un programme mais que vous ne trouvez pas les gadgets que vous utilisez généralement pour manipuler le comportement du programme.

Lorsqu'un programme utilise certaines bibliothèques (comme libc), il dispose de certaines fonctions intégrées pour gérer la communication entre différentes parties du programme. Parmi ces fonctions, certaines sont des joyaux cachés qui peuvent agir comme nos gadgets manquants, en particulier une appelée __libc_csu_init.

Les Gadgets Magiques dans __libc_csu_init

Dans __libc_csu_init, il y a deux séquences d'instructions (nos "gadgets magiques") qui se démarquent :

  1. La première séquence nous permet de configurer des valeurs dans plusieurs registres (rbx, rbp, r12, r13, r14, r15). Ce sont comme des emplacements où nous pouvons stocker des nombres ou des adresses que nous voulons utiliser ultérieurement.

pop rbx;
pop rbp;
pop r12;
pop r13;
pop r14;
pop r15;
ret;

Ce gadget nous permet de contrôler ces registres en extrayant des valeurs de la pile pour les y placer.

  1. La deuxième séquence utilise les valeurs que nous avons configurées pour faire quelques choses :

  • Déplacer des valeurs spécifiques dans d'autres registres, les rendant prêts à être utilisés comme paramètres dans des fonctions.

  • Effectuer un appel à une adresse déterminée en additionnant les valeurs dans r15 et rbx, puis en multipliant rbx par 8.

mov rdx, r14;
mov rsi, r13;
mov edi, r12d;
call qword [r15 + rbx*8];

Exemple

Imaginez que vous voulez effectuer un appel système ou appeler une fonction comme write() mais avez besoin de valeurs spécifiques dans les registres rdx et rsi en tant que paramètres. Normalement, vous chercheriez des gadgets qui définissent directement ces registres, mais vous n'en trouvez pas.

C'est là que ret2csu entre en jeu :

  1. Configurer les Registres : Utilisez le premier gadget magique pour dépiler les valeurs de la pile et les placer dans rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) et r15.

  2. Utiliser le Deuxième Gadget : Avec ces registres définis, vous utilisez le deuxième gadget. Cela vous permet de déplacer vos valeurs choisies dans rdx et rsi (à partir de r14 et r13, respectivement), préparant les paramètres pour un appel de fonction. De plus, en contrôlant r15 et rbx, vous pouvez faire en sorte que le programme appelle une fonction située à l'adresse que vous calculez et placez dans [r15 + rbx*8].

Vous avez un exemple utilisant cette technique et l'expliquant ici, et voici l'exploit final qu'il a utilisé :

from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

POP_CHAIN = 0x00401224 # pop r12, r13, r14, r15, ret
REG_CALL = 0x00401208  # rdx, rsi, edi, call [r15 + rbx*8]
RW_LOC = 0x00404028

rop.raw('A' * 40)
rop.gets(RW_LOC)
rop.raw(POP_CHAIN)
rop.raw(0)                      # r12
rop.raw(0)                      # r13
rop.raw(0xdeadbeefcafed00d)     # r14 - popped into RDX!
rop.raw(RW_LOC)                 # r15 - holds location of called function!
rop.raw(REG_CALL)               # all the movs, plus the call

p.sendlineafter('me\n', rop.chain())
p.sendline(p64(elf.sym['win']))            # send to gets() so it's written
print(p.recvline())                        # should receive "Awesome work!"

Notez que l'exploit précédent n'est pas destiné à faire une RCE, il est destiné à simplement appeler une fonction appelée win (en prenant l'adresse de win depuis stdin en appelant gets dans la chaîne ROP et en la stockant dans r15) avec un troisième argument ayant la valeur 0xdeadbeefcafed00d.

Pourquoi ne pas utiliser directement libc?

En général, ces cas sont également vulnérables à ret2plt + ret2lib, mais parfois vous devez contrôler plus de paramètres que ceux qui sont facilement contrôlés avec les gadgets que vous trouvez directement dans libc. Par exemple, la fonction write() nécessite trois paramètres, et trouver des gadgets pour définir tous ces paramètres directement pourrait ne pas être possible.

Dernière mise à jour