
Un chercheur de gadgets ROP multithreadé extrêmement rapide™. Alternative à ropper / ropgadget (actuellement x86 uniquement)
ropr est un chercheur de gadgets ROP multithreadé extrêmement rapide
Les gadgets ROP (Return Oriented Programming) sont de petits fragments de quelques instructions assembleur se terminant généralement par une instruction ret qui existent déjà en tant que code exécutable dans chaque binaire ou bibliothèque. Ces gadgets peuvent être utilisés pour l'exploitation binaire et pour subvertir des exécutables vulnérables.
Lorsque les adresses de nombreux gadgets ROP sont écrites dans un tampon, on forme une chaîne ROP. Si un attaquant peut déplacer le pointeur de pile vers cette chaîne ROP, alors le contrôle peut être complètement transféré à l'attaquant.
La plupart des exécutables contiennent suffisamment de gadgets pour écrire une chaîne ROP Turing-complète. Pour ceux qui n'en ont pas, on peut toujours utiliser les bibliothèques dynamiques contenues dans le même espace d'adressage, comme libc, une fois que l'on connaît leurs adresses.
La beauté de l'utilisation des gadgets ROP est qu'aucun nouveau code exécutable n'a besoin d'être écrit nulle part - un attaquant peut atteindre son objectif en utilisant uniquement le code qui existe déjà dans le programme.
Généralement, la première condition pour utiliser des gadgets ROP est d'avoir un endroit où écrire votre chaîne ROP - cela peut être n'importe quel tampon lisible. Écrivez simplement les adresses de chaque gadget que vous souhaitez utiliser dans ce tampon. Si le tampon est trop petit, il peut ne pas y avoir assez de place pour écrire une longue chaîne ROP, donc un attaquant doit faire attention à concevoir sa chaîne ROP de manière suffisamment efficace pour tenir dans l'espace disponible.
La condition suivante est de pouvoir contrôler la pile - Cela peut prendre la forme d'un débordement de pile - qui permet d'écrire la chaîne ROP directement sous le pointeur de pile, ou d'un "pivot de pile" - qui est généralement un seul gadget qui déplace le pointeur de pile vers le reste de la chaîne ROP.
Une fois que le pointeur de pile est au début de votre chaîne ROP, l'instruction ret suivante déclenchera l'exécution des gadgets en séquence - chacun utilisant le suivant comme adresse de retour sur sa propre trame de pile.
Il est également possible d'ajouter des pointeurs de fonction dans une chaîne ROP - en veillant à ce que les arguments de la fonction soient fournis après l'élément suivant de la chaîne ROP. Ceci est généralement combiné avec un "gadget pop", qui extrait les arguments de la pile afin de passer en douceur au gadget suivant après les arguments de la fonction.
Installation facile :
cargo install ropr
l'application s'installera dans ~/.cargo/bin
Depuis les sources :
git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo build --release
le binaire résultant se trouvera dans target/release/ropr
Alternativement :
git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo install --path .
l'application s'installera dans ~/.cargo/bin
USAGE:
ropr [OPTIONS] <BINARY>
ARGS:
<BINARY> The path of the file to inspect
OPTIONS:
-b, --base-pivot Filters for gadgets which alter the base pointer
-c, --colour <COLOUR> Forces output to be in colour or plain text (`true` or `false`)
-h, --help Print help information
-j, --nojop Removes "JOP Gadgets" - these may have a controllable branch,
call, etc. instead of a simple `ret` at the end
-m, --max-instr <MAX_INSTR> Maximum number of instructions in a gadget [default: 6]
-n, --noisy Includes potentially low-quality gadgets such as prefixes,
conditional branches, and near branches (will find significantly
more gadgets)
-p, --stack-pivot Filters for gadgets which alter the stack pointer
-r, --norop Removes normal "ROP Gadgets"
-R, --regex <REGEX> Perform a regex search on the returned gadgets for easy filtering
--range <RANGE> Search between address ranges (in hexadecial) eg. `0x1234-0x4567`
--raw <RAW> Treats the input file as a blob of code (`true` or `false`)
-s, --nosys Removes syscalls and other interrupts
-V, --version Print version information
Par exemple, si je cherchais un moyen de remplir rax avec une valeur provenant d'un autre registre, je pourrais choisir de filtrer par l'expression régulière ^mov eax, ...; :
❯ ropr /usr/lib/libc.so.6 -R "^mov eax, ...;" > /dev/null
==> Found 197 gadgets in 0.118 seconds
Maintenant, je peux ajouter quelques filtres sur la ligne de commande pour obtenir les résultats de la plus haute qualité :
❯ ropr /usr/lib/libc.so.6 -m 2 -j -s -R "^mov eax, ...;"
0x000353e7: mov eax, eax; ret;
0x000788c8: mov eax, ecx; ret;
0x00052252: mov eax, edi; ret;
0x0003ae43: mov eax, edx; ret;
0x000353e6: mov eax, r8d; ret;
0x000788c7: mov eax, r9d; ret;
==> Found 6 gadgets in 0.046 seconds
Maintenant, j'ai un bon candidat gadget mov à l'adresse 0x00052252