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

bf-decrypted.jpg