Microroptor - FCSC 2022

Microroptor - FCSC 2022

Fichiers du challenge Principe:
Forger un syscall dans un bufferoverflow pour contourner la protection NX

Le challenge

Un binaire exploitable (dispo ici) contient le flag
Il est chou ce "toutou"!

Overflow

On lance le prog dans edb et celui-ci nous renvoie une addresse (qui change)
On tente donc un overflow avec une longue entrée

Ne tenez pas compte du "whoami" et "exit", ce sont des essais random précédents

La stack montre un overflow lors du RET
…mais impossible de l'exploiter directement car on est en NX

NX: "No Execute", flag Linux interdisant l'exécution de code depuis la stack (l'équivalent Windows serait le DEP, Data Execution prevention)
Impossible donc d'utiliser l'overflow pour changer l'EIP/RIP (RIP = EIP 64 bits) et le faire pointer sur un payload sur la stack

On s'aperçoit qu'on est aussi en "Full RELRO", mais puisque le programme nous leak gentillement une adresse, on devrait pouvoir s'en servir pour retomber sur nos pattes.

Gadget chain

En explorant le binaire, une partie semble ne jamais être exécutée, et contient des instructions de syscall
Si on parvient à exécuter ces instructions (voir détails dans le zip des fichiers), alors on pourra obtenir une RCE et le flag

MOV $0x3b, %rax

On va éditer la stack à la main (pour les tests) et la faire pointer vers le POP RAX qu'on a trouvé
Cette instruction va mettre, dans RAX, l'élément suivant dans la stack (ici Ab6Ab7Ab)
On va donc l'éditer à la main pour mettre 3b
On exécute l'instruction (F8) et on a bien 3b dans le registre RAX

lea str_addr, %rdi

On va éditer l'entrée suivante dans la stack, et la faire pointer vers le POP RDI
On va insérer notre string /bin/bash (la commande qu'on souhaite exécuter via syscall) dans la stack (un peu n'importe où), et faire pointer l'élément suivant de la stack dessus (à la main)
On exécute l'instruction et on se retrouve bien avec un RDI qui pointe vers notre string /bin/bash

mov $0, %rsi

On trouve (un peu au hasard) des instructions permettant de passer le RSI à 0: on pointe donc dessus, et on continue

Les screen n'ayant pas été prises dans la même exécution, les adresses ont changé, mais le principe reste le même

mov $0, %rdx

On édite de nouveau l'élément suivant dans la stack pour pointer vers POP RDX
On exécute l'instruction, on se retrouve sur le POP RDX, et on met 0 dans la stack
On exécute l'instruction et on a bien RDX=0

syscall

On met l'adresse du syscall à la main
On exécute et on se retrouve sur l'instruction syscall
Et on a notre shell, en debug

Assemblage

A partir de l'adresse leakée (baseAddr), on calcule les adresses vers lesquelles on doit pointer, et on construit notre payload

Le $payload est donc constitué de:
- quelques caractères bidons pour l'overflow
- l'adresse trouvée permettant, une fois le RET atteint, d'avoir RSI = 0 - l'adresse POP RAX - la valeur qui sera mise dans RAX (0) - l'addresse de POP RDI - la valeur qu'on va mettre dans RDI (basée sur l'offset de la stack) - l'adresse du POP RDX - la valeur à mettre dans RDX - l'adresse du syscall - quelques caractères bidon (de la marge, dont on pourrait éventuellement se passer) - la commande à exécuter (/bin/bash) - d'autres caractères bidons (de la marge encore)

On pourrait se passer des caractères bidons de "marge", mais cela obligerait à recalculer les offsets et pourrait, parfois, amener d'autres changement de comportement. Donc, je les ai conservés.

Livraison

Comme d'habitude, ma plus grosse galère consiste à livrer le payload.

On va se servir de cat|./program (à gauche) et laisser un script PHP tourner (à droite) pour livrer le payload: le shell apparait alors (à gauche)

Le script PHP attend qu'on lui copie/colle l'adresse donnée par le programme, puis il cherche le programme dans les process en cours, et lui envoie le payload.
On pourrait sans doute faire plus élégant, mais bon…

Flag

On fait la même sur le challenge, et le flag tombe:
FCSC{e3752da07f2c9e3a0f9ad69679792e5a8d53ba717a2652e29fb975fcf36f9258}

Apparemment, certains ont utilisé l'approche ret2libc mais bon, je trouvais celle-ci plus adéquate, puisqu'elle exploite un bout du binaire gentillement laissé ici par les organisateurs du CTF!

Fichiers du challenge

↩ Retour à la liste des challenges

⇇ Retour à l'accueil