NDH2k11 Prequals - Crypto200
By awe on Tuesday, April 5 2011, 19:23 :: Prequals ndh2k11 :: Permalink
On a un code source qui génère des password au hasard et un fichier jpg encrypté.
Un block de 8 bytes qui commence à un rang multiple de 8 bytes se répète très très souvent. Plusieurs fois de suite, au début, au milieu, à la fin...
On comprend donc que c'est un chiffrement symmétrique par blocks de 64-bits du genre de DES. On se doute aussi que le block de 8 qui se répète correspond à un byte répété plusieurs fois de suite, très probablement des null bytes vu la structure des jpg en général.
Vu le nom du fichier (bf-encrypted.jpg) on devine que c'est du BlowFish (c'est bien du DES-like).
Du coup on a pas vraiment le choix, il faut bruteforcer.
Vu le fichier de génération de password fourni on devine que la longueur de la clef est de 8 bytes. ymvunjq y trouve une faille qui permet de ne bruteforcer que sur les 5 premiers bytes (les 3 suivants sont déduits par la suite).
Ainsi on lance un bruteforce qui passe par les 62^5 passes possibles (62 étant le nombre de caractères dans le charset).
BAAL trouve le passe eynnoXAd. On l'utilise pour dé-blowfisher l'image avec le code suivant:
#include "blowfish.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void bruteforce_key (void) { unsigned long L = 1, R = 2; BLOWFISH_CTX ctx0; char PASS[10] = {0}; // Test to check if the blowfish code runs properly on given computer Blowfish_Init (&ctx0, (unsigned char*)"TESTKEY", 7); Blowfish_Encrypt(&ctx0, &L, &R); printf("%08lX %08lX\n", L, R); if (L == 0xDF333FD2L && R == 0x30A71BB4L) printf("Test encryption OK.\n"); else printf("Test encryption failed.\n"); Blowfish_Decrypt(&ctx0, &L, &R); if (L == 1 && R == 2) printf("Test decryption OK.\n"); else printf("Test decryption failed.\n"); // Bruteforce, loop through first 5 chars char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!$%*+[]()"; int a0, a1, a2, a3, a4; for(a0=0;a0<62;a0++){ for(a1=0;a1<62;a1++){ printf("%i %i - ", a0, a1); // Display progress for(a2=0;a2<62;a2++){ for(a3=0;a3<62;a3++){ for(a4=0;a4<62;a4++){ PASS[0] = charset[a0]; PASS[1] = charset[a1]; PASS[2] = charset[a2]; PASS[3] = charset[a3]; PASS[4] = charset[a4]; PASS[5] = charset[PASS[4] % 62]; PASS[6] = charset[PASS[5] % 62]; PASS[7] = charset[PASS[6] % 62]; L = 0; R = 0; Blowfish_Init (&ctx0, (unsigned char*)PASS, 8); Blowfish_Encrypt(&ctx0, &L, &R); if (L == 0x8EDE92F0 && R == 0xD0D99926){ //Expected crypted text printf("*** Success *** Password: %s\n", PASS); a0 = 100; a1 = 100; a2 = 100; a3 = 100; a4 = 100; system("PAUSE"); } } } } } } puts ("[+] DONE"); } void decrypt (void) { BLOWFISH_CTX ctx0; unsigned long L = 0x67A2204C , R = 0x967FB36E; int i; FILE *input = fopen ("bf-encrypted.jpg", "rb"); FILE *output = fopen ("bf-decrypted.jpg", "wb+"); if (!input) { puts ("[-] File not found"); return; } while (!feof (input)) { L = 0; R = 0; for (i = 0; i < 4; i++) L = (L << 8) + fgetc (input); for (i = 0; i < 4; i++) R = (R << 8) + fgetc (input); Blowfish_Init (&ctx0, (unsigned char*)"eynnoXAd", 8); // This is the password obtained from step 1 Blowfish_Decrypt(&ctx0, &L, &R); for (i = 0; i < 4; i++) fputc ((L >> (8 * (3 - i))) & 0xff, output); for (i = 0; i < 4; i++) fputc ((R >> (8 * (3 - i))) & 0xff, output); } fclose (input); fclose (output); puts ("[+] DONE"); } int main(int argc, char **argv) { if (argc < 2) { printf ("Usage: %s step\n" "\tStep 1 : Bruteforce the key\n" "\tStep 2 : Decrypt the ciphertext\n", argv[0]); return 1; } if (argv[1][0] == '1') bruteforce_key (); else if (argv[1][0] == '2') decrypt (); else puts ("[-] FAIL\n"); return 0; }
Le code source du blowfish est pris d'ici: C'est celui de Paul Kocher.
L'image une fois décryptée donne le flag: Cod3monk3ys_4re_3viL

