Pas de mise à jour (Reverse) - 404CTF 2022

Pas de mise à jour (Reverse) - 404CTF 2022

Fichiers du challenge Principe:
Décompiler un script Python pyc, le lire et reconstituer l'algorithme de chiffrement du mot de passe pour retrouver ledit mot de passe

Le challenge

Il faut encore une fois retrouver un mot de passe dans un CPython (python compilé, dispo ici)

Testons

On teste déjà le pyc (Python compilé) et on confirme qu'il marche bien
Dans le dump hexa du fichier, on voit qu'il implique une source temporaire et on repère un mot de passe également
Dans le doute, je me suis dit "peut-être que le script génère un python en clair dans /tmp et l'exécute?" mais non, ce n'est pas le cas

Décompiler python avec Python

Uncompyle

On va donc décompiler le script pyc avec… Python! uncompyle permet ça

Il me semble toujours plus logique d'utiliser un "décompilateur" proche du langage d'origine. S'il faut "décompiler" du Python, il existe sûrement des paquets Python ou liés à Python pour ça. De même, s'il s'était agit de PHP, il y aurait sûrement eu des fonctions de PHP ou des paquets liés à PHP permettant de faire cette décompilation

Je hais Python

Malheureusement, j'ai des incompatibilités entre uncompyle et Python 3.10

Pycdc

J'essaie alors un autre décompilateur (pycdc ou Decompyle++): je clone le repo Git, je build
Et je le lance sur le pyc du challenge (enfin, sur une copie, comme je vous l'ai conseillé )
Mise à part la non-prise en charge de match issue de Python 3.10, tout va bien
Match
En utilisant pycdas de pycdc, on récupère un fichier avec les instructions, les variables, et tout ce qu'il faut
On s'aperçoit aussi que l'instruction MATCH_SEQUENCE est, cette fois, bien comprise et décompilée

Python assembleur

Là, il faudra lire la documentation de Python, qui se trouve très facilement en cherchant les instructions décompilée l'une après l'autre

La plupart des instructions sont toutefois compréhensible facilement, comme COMPARE_OP ou LOAD_CONST

On trouve alors que le i-eme caractère mdp[i] suit l'algorithme code[i] = (5*ord(mdp[i])) XOR BINARY_TO_DECIMAL_INT(key[(30-i)%LENGTH(key)])

Pour arriver à cela, le mieux est probablement de prendre une feuille de papier, et de "simuler" ce que font les instructions avec la stack mémoire pour saisir la logique de l'algorithme.

Flag

Une fois l'algo de chiffrement compris, il n'est pas compliqué de scripter un décodeur:
404CTF{R34D1NG_PYTH0N_BYT3C0D3}

Fichiers du challenge

↩ Retour à la liste des challenges

⇇ Retour à l'accueil