UnitedCTF / UnitedCTF-2020

Défis et solutions de l'éditions UnitedCTF-2020
12 stars 1 forks source link

Track Reverse #3

Closed xshill closed 4 years ago

AXDOOMER commented 4 years ago

Outline des challenges que je prévois faire:

  1. Le typique binaire de base que tu fais strings dessus et qui te donne le flag. Ghidra pas nécessaire. "blah\0flag\0"?
  2. Premier challenge qui demande Ghidra. Un binaire avec une lib statically linked, il y a une fonction dedans très simple qui encode un flag et qui est jamais appelée. puts("Is something missing?") (add deux arrays ensemble, puts le résultat ASCII) S'assurer que la lib a un nombre raisonnable de fonctions (OpenSSH?).
  3. Un one-time pad (si la décompilation dans Ghidra rend ça trop évident, je peux le faire en C++ ou XOR quatre caractères à la fois et les comparer comme un integer). Peut-être qu'il faudra mettre des anti-debug dans celui-là. L'allocation de mémoire (new/delete) peut aider à obscurcir.
  4. Crackme. Jeu de contraintes avec des additions, soustractions, divisions, multiplications, XOR, ROR/ROL. Il doit y avoir une seule string qui répondra aux contraintes. (compiler en MIPS pour rendre la décompilation moins claire?) Le \0 à la fin du string pourrait être utilisé dans une contrainte (il faut savoir que les strings en C finissent par un null byte), ça pourrait rendre confus le participant dans le cas où on ne spécifie pas la longueur du input.
  5. Tooslow, premier challenge où le participant devra modifier le binaire. Va nécessiter des anti-debug et anti-LD_PRELOAD. On peut suggérer au participant d'utiliser Radare2 pour modifier le binaire ou son hex editor préféré s'il aime lire les opcodes :trollface:. Mersenne twister (C++) qui affiche des lignes d'un poème. Chaque ligne prend une seconde à afficher (sleep, usleep, nanosleep, system("sleep 1") et/ou memfd de sleep qu'on exec). Il faut NOP ou modifier les paramètres de chaque fonction sleep pour les enlever ou NOP les appels. À chaque itération, un array est xoré (XOR avec décalage) jusqu'à après 100 000 itérations où on obtient le résultat. Pour les sleeps, on pourrait utiliser des pointeurs de fonction pour rendre la décompilation moins évidente ou des shellcodes. (memfd de sleep qu'on exec avec un syscall augmente la difficulté et peut rendre ça beaucoup plus intéressant, on peut aussi vérifier l'altération du binaire)
  6. Intelligent bruteforce. Fonction de type CRC ou checksum qui calcul un hash sur une lettre du input à la fois. Si c'est bon, on passe à la prochaine lettre (Time-based attack). Pas super long à reverse, mais requiert de la programmation une fois qu'on a compris le problème et qu'on trouve l'attaque à faire. Le solveur se script bien avec Bash ou Python (GDB peut interagir avec des scripts Python).
  7. Programme Rust qui génère un hex aléatoire (toujours le même seed) à la fois qui est XOR avec un one-time pad. On compare un char à la fois avec le input. Avec une bonne compréhension, le participant peut le debug et aller chercher tous les chars pour former le flag.
  8. Final boss? Ça pourrait être un one-time pad en Golang. (difficile si t'as jamais reverse du Go)

Feedback is welcome of course :-)

Je vais commencer à programmer ça prochainement.

AXDOOMER commented 4 years ago

Track simplifiée:

  1. Le typique binaire de base que tu fais strings dessus et qui te donne le flag. Ghidra pas nécessaire. ("blah\0flag\0"?)
  2. Le binaire vérifie un password, après le flag est décodé et sera imprimé à l'écran. (Tu peux voir le password dans la décompilation ou en faisant strings)
  3. Premier challenge qui demande Ghidra. Créer le flag à partir de strings sur la stack. (array de chars, on pige des ensembles de quatre chars pour construire le flag. On le print pas à l'écran). Le participant doit examiner la décompilation pour reconstruire le flag.
  4. Binaire avec un main qui contient seulement puts("Is something missing?\0A function call maybe?"). Il y a une fonction dedans qui encode un flag et qui est jamais appelée. (add deux arrays ensemble, puts le résultat ASCII). Pas de static lib pour que le participant aille 20 fonctions à checker dedans max. (peut se faire avec http://www.asciitable.com/)
  5. Un one-time pad qui compare un char à la fois. (peut se faire avec http://xor.pw/)
  6. Crackme. Jeu de contraintes avec des additions, soustractions, divisions, multiplications, shift, XOR, ROR/ROL. Il doit y avoir une seule string qui répondra aux contraintes. Le \0 à la fin du string pourrait être utilisé dans une contrainte (il faut savoir que les strings en C finissent par un null byte), ça pourrait rendre confus le participant dans le cas où on ne spécifie pas la longueur du input. (peut être expliqué dans un hint, peut se faire avec CyberChef et d'autres outils en ligne)
  7. Tooslow, premier challenge où le participant devra modifier le binaire. Il peut aussi faire un LD_PRELOAD (ça pourrait être un hint). Mersenne twister (C++) qui affiche des lignes d'un poème. Chaque ligne prend une seconde à afficher (sleep, usleep, nanosleep, system("sleep 1")). Il faut NOP ou modifier les paramètres de chaque fonction sleep pour les enlever ou NOP les appels, ou faire un LD_PRELOAD. À chaque itération, un array est xoré (XOR avec décalage) jusqu'à après 100 000 itérations où on obtient le résultat.
  8. Fonction de type CRC ou checksum qui calcule un hash (en hex) et qui fait plusieurs itérations. Le participant doit entrer la string hex qui est générée au runtime. (premier challenge qui nécessite GDB et Peda).
Res260 commented 4 years ago

looks nicer :D

--Émilio

On Sun, 5 Jul 2020 at 14:56, Alexandre-Xavier Labonté-Lamoureux < notifications@github.com> wrote:

Track simplifiée:

  1. Le typique binaire de base que tu fais strings dessus et qui te donne le flag. Ghidra pas nécessaire. ("blah\0flag\0"?)
  2. Le binaire vérifie un password, après le flag est décodé et sera imprimé à l'écran. (Tu peux voir le password dans la décompilation ou en faisant strings)
  3. Premier challenge qui demande Ghidra. Créer le flag à partir de strings sur la stack. (array de chars, on pige des ensembles de quatre chars pour construire le flag. On le print pas à l'écran). Le participant doit examiner la décompilation pour reconstruire le flag.
  4. Binaire avec un main qui contient seulement puts("Is something missing?\0A function call maybe?"). Il y a une fonction dedans qui encode un flag et qui est jamais appelée. (add deux arrays ensemble, puts le résultat ASCII). Pas de static lib pour que le participant aille 20 fonctions à checker dedans max. (peut se faire avec http://www.asciitable.com/)
  5. Un one-time pad qui compare un char à la fois. (peut se faire avec http://xor.pw/)
  6. Crackme. Jeu de contraintes avec des additions, soustractions, divisions, multiplications, shift, XOR, ROR/ROL. Il doit y avoir une seule string qui répondra aux contraintes. Le \0 à la fin du string pourrait être utilisé dans une contrainte (il faut savoir que les strings en C finissent par un null byte), ça pourrait rendre confus le participant dans le cas où on ne spécifie pas la longueur du input. (peut être expliqué dans un hint, peut se faire avec CyberChef et d'autres outils en ligne)
  7. Tooslow, premier challenge où le participant devra modifier le binaire. Il peut aussi faire un LD_PRELOAD (ça pourrait être un hint). Mersenne twister (C++) qui affiche des lignes d'un poème https://www.poetryfoundation.org/poems/48860/the-raven. Chaque ligne prend une seconde à afficher (sleep, usleep, nanosleep, system("sleep 1")). Il faut NOP ou modifier les paramètres de chaque fonction sleep pour les enlever ou NOP les appels, ou faire un LD_PRELOAD. À chaque itération, un array est xoré (XOR avec décalage) jusqu'à après 100 000 itérations où on obtient le résultat.
  8. Fonction de type CRC ou checksum qui calcule un hash (en hex) et qui fait plusieurs itérations. Le participant doit entrer la string hex qui est générée au runtime. (premier challenge qui nécessite GDB et Peda).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/UnitedCTF/UnitedCTF-2020/issues/3#issuecomment-653925469, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADPMNLYBJVVUFCZKP7SFQWLR2DEFLANCNFSM4OPNFXCA .

AXDOOMER commented 4 years ago

Good. Je pense pas vraiment pouvoir faire plus facile sans que ça reste un défi. Si par exemple, résoudre un one-time pad est trop compliqué pour le participant, on pourrait lui faire faire le "1 byte XOR challenge" en premier pour qu'il se fasse une meilleure idée de ce que c'est.

Pour un participant qui ne sait pas programmer, le challenge 7 devrait être faisable avec des recherches Google et un peu de débrouillardise.

AXDOOMER commented 4 years ago

image image