0
$\begingroup$

I am reverse engineering the firmware of a particular router/modem. I am focusing on the functionality to export the router configuration. I an searching for a way to decrypt the configuration backup file.

I have the source code of the open source parts of the firmware and the binaries of the closed source parts for analysis.

After an analysis of the binary responsible for creating the configuration backup file i discovered it does the following:

  1. Takes the raw XML configuration file
  2. Compresses the file
  3. Encrypts the file using a key and an iv (more on that later)
  4. Applies a PKCS7 signature to the file

To encrypt the configuration file a 256 bit AES key is used, in CBC mode. We will call this key file key.

To derive the file key two pieces of information are used: a user password and a device key, combined in the following way:

file_key = MD5(user_password) + MD5(device_key)

where the user_password is just a string choosen by the user during the config export process in the web interface of the router.

The device_key is an AES key, generated once (the first time is used) and then saved on a file (and read from there when is used again). During the generation of the AES key also an IV is generated and saved along the key. The is generated once and reused the following times.

This device_key (and the associated IV) is used only to encrypt/decrypt the configuration backup.

The crypto library used is openssl-1.0.2k

This is a C code that describes how is generated the device_key (and the associated IV). Is called only once and the results are reused.

const EVP_CIPHER *cipher_algo;
const EVP_MD *digest_algo;

unsigned char salt[8];
unsigned char device_key[32];
unsigned char device_key_iv[16];

// yes, the secret key material is constant and is "secret"
char secret_data[] = "secret";

cipher_algo = EVP_aes_256_cbc();
digest_algo = EVP_md5();

// in the code the result of this call is NOT checked to be sure it succeded,
// maybe something here?
RAND_pseudo_bytes(salt, 8); 

// here the device_key is generated
EVP_BytesToKey(cipher_algo, digest_algo, salt, secret_data, strlen(secret_data), 1, device_key, device_key_iv);

// from now on the device_key and device_key_iv is never regenerated

This is a C code that describes how is generated the file_key. It is called every time a backup configuration file is exported.

unsigned char device_key[32]; 
unsigned char device_key_iv[16];

char user_password[] = "test1234";
unsigned char file_key_raw[32];

MD5_CTX md5_context;
AES_KEY file_key_aes;

get_device_key_and_iv(device_key, device_key_iv);


// hash of user password
MD5_Init(&md5_context);
MD5_Update(&md5_context, user_password, strlen(user_password));
MD5_Final(file_key_raw, &md5_context);

// hash of device_key
MD5_Init(&md5_context);
MD5_Update(&md5_context, device_key, 32);
MD5_Final(&file_key_raw[16], &md5_context);

// now file_key_raw contains the raw bytes of the key 

AES_set_encrypt_key(file_key_raw, 256, file_key_aes);

// now the struct file_key_aes contains the file_key

//to encrypt data, this is called:
AES_cbc_encrypt(input_data_buffer, output_data_buffer, len_of_input_data, file_key_aes, device_key_iv, 1);

Are there implementation/usage bugs that can allow to recover the file key without a full bruteforce?

$\endgroup$

migrated from security.stackexchange.com Sep 9 at 18:28

This question came from our site for information security professionals.

  • 1
    $\begingroup$ Well, it's using plain MD5 which is not a good password hashing algorithm... $\endgroup$ – forest Aug 21 at 23:43
  • $\begingroup$ The device key only has 64 bits of entropy. The user password has as much entropy as the user entered, for user generated passwords often fewer than 20 bits. If the attacker has only the encrypted config backup file and not the device key (or device to extract key from), I think it's too hard to brute force. With the device key, code like hashcat to brute force the user password is easy and anything short of a computer generated password will be broken. $\endgroup$ – Z.T. Aug 21 at 23:49
  • 1
    $\begingroup$ It does not use authenticated encryption, but I suppose the digital signature protects against attacks on a CBC padding oracle (if one is present). If you have a backup file for which you know the password, but you don't know the device key, you can try brute forcing the device key (64 bits of entropy) by finding which one decrypts the backup you have. Then you can try to brute force the user password on the backup file for which you don't know the password. This is feasible, but too expensive to do unless it's super valuable. $\endgroup$ – Z.T. Aug 22 at 0:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.