FCSC : Crackage de calculatrice et stéganographie

Bonjour à tous :), juste après le hackday vient maintenant le FCSC, CTF individuel cette fois. Je commence avec un write-up portant sur le challenge de teasing, qui mêle stéganographie et cracking. Trêve de blabla, c’est parti !

Sommaire

  • Partie 1 : Stéganographie
  • Partie 2: Reverse engineering du programme pour calculatrice

Partie 1: Stéganographie

Après un petit coup sur https://aperisolve.fr/, on s’aperçoit qu’il y a des dinosaures cachés dans l’image.

Après pas mal de recherche google, je tombe sur

Les caractères correspondent à ceux sur l’image, seulement il en manque quelques-uns. Je cherche alphabet Ding-o-saurs sur google, et je tombe sur le site dafont qui m’apprend que c’est une police d’écriture ! (que j’installe d’ailleurs).

Je recopie chaque caractère dans word avec la police ding-o-saurs.

Je m’aperçois qu’il y a encore un chiffrement. Par réflexe, Je m’empresse de tester s’il ne s’agit pas d’un chiffrement par décalage, mais il s’agit d’autre chose. On remarque le :// qui semble correspondre avec un site web. De plus, le nombre de caractères entre les tirets correspond avec l’url du site web du FCSC: https://france-cybersecurity-challenge.fr. On se base sur ça pour construire un alphabet, et on décode:

text = """
WKSMGMGHIMOQOYJOPSIIOKVSPKODLOKOOUSPO
JOZOZCSVVOQBOMGHIUKGHMOKOYVSNLQSZOUUO
SJKOIIOCUUPI ://NKSQZO-ZTWOKIOZHKLUT-
ZCSVVOQBO.NK/WPWZDKPVNBYDYUBBBPWZ
"""
text = text.replace("C","h").replace("U","t").replace("P","p").replace("I","s").replace("N","f").replace("K","r").replace("S","a").replace("Q","n").replace("Z","c").replace("O","e")
text = text.replace("V","l").replace("B","g").replace("T","y").replace("W","b").replace("H","u").replace("L","i").replace("M","v").replace("G","o").replace("D","m").replace("Y","z")
text = text.replace("J","d")
print(text)

Ce qui nous affiche:

bravo vous venez de passer la premiere etape de ce challenge vous trouverez la fina cette
adresse https://france-cybersecurity-challenge.fr/bpbcmrplfgzmztgggpbc


Partie 2: Reverse engineering du programme pour calculatrice

1. Prise d’informations

On ouvre directement le fichier dans Hxd, à la recherche d’informations pertinentes.

Humm, il semblerait qu’il s’agit d’un programme se lançant sur calculatrice Texas Instrument, et plus précisément sur le modèle TI-83. On note également la taille du password: 32 caractères. En googlant un peu, on tombe sur un write-up qui nous indique l’outil dont on va se servir: « TilEm Debugger ». On télécharge également la ROM fourni dans le write-up. On lance TilEm, puis clique droit, open calculator, et on y balance la ROM. Puis clique droit, send, fcsc.8xp.

On lance notre programme en réalisant l’opération Asm(prmFCSC). ( 2nd > 0 pour ouvrir le catalogue, puis on sélectionne Asm, et PRGM > prmFCSC).

Pour ma part, j’ai d’abord essayé de trouvé le flag en statique, avec la version pro d’IDA. On commence par cherché le modèle de processeur utilisé dans les TI-83.

Il s’agit d’un processeur zilog z80. On trouve de la documentation sur le jeu d’instruction assembleur ici, et sur les registres du processeurs ici.

2. Analyse statique

On lance IDA pro, on ouvre notre fichier et on sélectionne le processeur zilog z80. On laisse les paramètres par défaut, et on commence notre étude statique.

On remarque tout de suite cette succession de xor. On prend soin de noté chaque valeur, et surprise, il y en a 32, comme la taille de la clé ! (mais si rappelez-vous).

[0xc2,9,0x0d,0x0a,7,0xc,9,0×10,0x14,7,6,0xe,0xa,0xf,0xb,0xa,0xa,1,8,0xc,0xa,8,7,0xe,0x1a,0x1c,7,0xb,0x10,0x1F,2,3]

J’ai ensuite cherché une autre chaine de 32 caractères, le flag xoré avec la clé, mais sans succès. Je suis donc parti à la recherche du flag en me lançant dans une étude dynamique, cette fois.

3. Analyse dynamique

Bon, là ça a été un peu laborieux. J’ai pas mal pataugé dans le debugger, car on y trouve le code assembleur de toute l’exécution de la calculatrice (Ca inclut l’affiche des caractères). Pour me repérer, j’ai cherché assembleur le code trouvé précédemment dans IDA, qu’on trouve au niveau des adresses 0X419DXX.

On pose des breakpoints dans cette zone, et on observe des choses très intéressantes, en modifiant la valeur du registre PC (qui contient l’adresse de la prochaine instruction à exécuter).

On détermine alors les choses suivantes:

AdresseInstructionAction
0x419D9Ecall getkeyAttends une entrée de l’utilisateur après l’affichage du message de bienvenue
0x419DA1call ClrLCDFULLEfface l’écran
0x419DAAcp $20Vérifie que la taille de l’input est bien de 32 caractères
0x419DB8 call 0x419FC5Affiche « perdu… »
0x419DBDcall 0x419F87Affiche « gagné, le flag est »
0X419DAEcall 0x419F65Lance une série d’instruction qui vérifie que l’input est bien le flag

On cherche ensuite notre input dans la zone de mémoire que l’on trouve à l’adresse 0x41A0A2. On comprends comment sont codé les caractères: de 0x8e à 0x97, les nombres 0,1,2,3,4,5,6,7,8,9 et de 0x9A à 0x9F les lettres A,B,C,D,E,F. Par exemple, si j’envoie 32 fois 7 dans l’input, on obtient 32 fois 95.

Passons maintenant à la fonction xor déjà étudié précédemment.

Pour résumer ce que fait la fonction: elle load une valeur dans le registre A. Elle xor le registre A, puis elle compare cette valeur avec celle se trouvant à IX, qui s’avère être notre input. Si les 2 valeurs s’avèrent être les mêmes, ça affiche un 1 sur l’écran, puis ça passe au caractère suivant en incrémentant IX de 1. Si ce n’est pas le cas, ça n’affiche pas le 1 sur l’écran, mais ça enchaine quand même aux caractères suivants. On comprend alors que notre objectif est que l’input soit égal à la valeur du registre A après le xor. En posant un break à chaque CP (IX) et en notant chaque valeur de A, on obtient:

flag = [0x92,0x9b,0x96,0x9c,0x9b,0x97,0x9e,0x8e,0x9a,0x9d,0x9b,0x95,0x9f,0x90,0x9b,0x91,
0x9b,0x9a,0x92,0x9e,0x94,0x9c,0x9b,0x95,0x8f,0x93,0x94,0x9f,0x8f,0x90,0x92,0x91]

Il ne reste plus qu’à transformer chaque valeur hexadécimal en caractère.

flag = [0x92,0x9b,0x96,0x9c,0x9b,0x97,0x9e,0x8e,0x9a,0x9d,0x9b,0x95,0x9f,0x90,0x9b,0x91,
     0x9b,0x9a,0x92,0x9e,0x94,0x9c,0x9b,0x95,0x8f,0x93,0x94,0x9f,0x8f,0x90,0x92,0x91]
decrypt_flag = ""

for i in flag:
    if i >= 0x9a:
        decrypt_flag += hex(i)[-1]
    else:
        decrypt_flag += chr(i-0x5e) 
print(decrypt_flag)
'''
FCSC{4b8cb9e0adb7f2b3ba4e6cb7156f1243}
'''

Voilà pour la première épreuve de ce FCSC 2022. L’aventure continue !

fcsc.8xp , TI-testrom.rom