[CTF GEMA] Try Harder
CTF GEMA Groupe 2025
Niveau de Difficulté : Hard
Catégorie du Challenge : Reverse
Description :
More layer more security ?!
Steps to Solve
Programme PE : Chiffrement d'un mot de passe
Le programme PE fourni chiffre un mot de passe de 30 caractères entré par l'utilisateur et vérifie si le résultat chiffré correspond à une chaîne hexadécimale prédéfinie.
Étapes du chiffrement
Gestion de l'entrée
- Le programme demande à l'utilisateur d'entrer un mot de passe de 30 caractères.
- Il vérifie que la longueur de l'entrée est exactement de 30 caractères.
Conversion en binaire
- La fonction toBinary convertit le tableau de caractères (password) en un tableau d'entiers non signés (data), où chaque caractère est représenté par sa valeur ASCII.
Transformations de chiffrement
- s1t : Effectue un décalage à gauche de 5 bits sur chaque entier du tableau.
- s2t : Effectue une opération XOR sur chaque entier avec les caractères
'C'
et'M'
. - s3t : Effectue un décalage à droite de 5 bits sur chaque entier du tableau.
- s4t : Échange les 10 premiers bits avec les 10 derniers bits de chaque entier du tableau.
Conversion en hexadécimal
- La fonction printHex convertit le tableau d'entiers transformé en une chaîne hexadécimale unique (
encryptedHex
).
Comparaison
- Le programme compare la chaîne hexadécimale obtenue avec une chaîne hexadécimale attendue.
- Il affiche "correct!!" si elles correspondent et "bad" sinon.
📌 Le nom de la fonction de chiffrement n'est pas visible.
Résumé du code de déchiffrement
Le programme C fourni prend une chaîne hexadécimale chiffrée en entrée, la déchiffre en utilisant une série d'opérations bitwise et de transformations, puis affiche le mot de passe original de 30 caractères.
Étapes du déchiffrement
Gestion de l'entrée
- Le programme demande à l'utilisateur d'entrer une chaîne hexadécimale de 240 caractères, représentant le mot de passe chiffré.
- Il vérifie que la longueur de l'entrée est exactement de 240 caractères.
Conversion depuis l'hexadécimal
- La fonction hexToIntArray convertit la chaîne hexadécimale en un tableau d'entiers non signés (
data
).
Transformations de déchiffrement
- s4t_reverse : Annule l'échange des bits en rééchangeant les 10 premiers bits avec les 10 derniers bits de chaque entier.
- s3t_reverse : Annule le décalage à droite de 5 bits en effectuant un décalage à gauche de 5 bits.
- s2t_reverse : Effectue une opération XOR sur chaque entier avec les caractères
'M'
et'C'
. - s1t_reverse : Annule le décalage à gauche de 5 bits en effectuant un décalage à droite de 5 bits.
Conversion en caractères
- La fonction intArrayToChar convertit le tableau d'entiers transformé en une chaîne de caractères (
password
).
Résultat
- Le programme affiche le mot de passe déchiffré.
Fonctions utilisées
- hexToIntArray : Convertit une chaîne hexadécimale en tableau d'entiers non signés.
- s4t_reverse : Annule l'échange des 10 premiers et 10 derniers bits.
- s3t_reverse : Décale chaque élément à gauche de 5 bits (annulant le décalage à droite).
- s2t_reverse : Effectue un XOR avec
'M'
et'C'
. - s1t_reverse : Décale chaque élément à droite de 5 bits (annulant le décalage à gauche).
- intArrayToChar : Convertit le tableau d'entiers en chaîne de caractères.
decrypt.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void hexToIntArray(char *hex, unsigned int *data, int size) {
for (int i = 0; i < size; ++i) {
sscanf(hex + 8 * i, "%08x", &data[i]);
}
}
void s4t_reverse(unsigned int *data, int size) {
for (int i = 0; i < size; ++i) {
unsigned int first10 = (data[i] >> 22) & 0x3FF;
unsigned int last10 = data[i] & 0x3FF;
data[i] = (data[i] & 0xFFFFFC00) | first10;
data[i] = (data[i] & 0x003FFFFF) | (last10 << 22);
}
}
void s3t_reverse(unsigned int *data, int size) {
for (int i = 0; i < size; ++i) {
data[i] <<= 5;
}
}
void s2t_reverse(unsigned int *data, int size) {
for (int i = 0; i < size; ++i) {
data[i] ^= 'M';
data[i] ^= 'C';
}
}
void s1t_reverse(unsigned int *data, int size) {
for (int i = 0; i < size; ++i) {
data[i] >>= 5;
}
}
void intArrayToChar(unsigned int *data, char *str) {
for (int i = 0; i < 30; ++i) {
str[i] = (char)data[i];
}
str[30] = '\0';
}
int main() {
char hex[241];
printf("Enter the encrypted text in hex: ");
fgets(hex, 241, stdin);
if (strlen(hex) != 240) {
fprintf(stderr, "Encrypted text must be exactly 240 characters.\n");
return 1;
}
unsigned int data[30] = {0};
char password[31] = {0};
hexToIntArray(hex, data, 30);
s4t_reverse(data, 30);
s3t_reverse(data, 30);
s2t_reverse(data, 30);
s1t_reverse(data, 30);
intArrayToChar(data, password);
printf("Decoded password: %s\n", password);
return 0;
}
Flag
FLAG{im_here_if_you_can_find!}