Contenido principal

VirtualBox Disk Image Encryption password cracker

Julio 15, 2015

VirtualBox 5.0 was released the past July 9 with a new built-in disk image encryption feature which allows the user to encrypt virtual hard disk transparently.

With this feature a new tab is enabled in General configuration for each machine:

VBOXDIE Configuration

When the user sets a password, a new element called Property is added to the HardDisk element inside the machine configuration:

<HardDisk uuid="{b9f72e2c-7dde-412d-be98-6f07dbcabd41}" location="Encrypted.vdi" format="VDI" type="Normal">
  <Property name="CRYPT/KeyId" value="Encrypted"/>
  <Property name="CRYPT/KeyStore"
value="U0NORQABQUVTLVhUUzEyOC1QTEFJTjY0AAAAAAAAAAAAAAAAAABQQktERjItU0hB
MjU2AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAJwd3SksjYgaKyVqNkFvSNya8SkGiz
kfuKYCB2xJk67SAAAACbTjDwMkoPESRduJWBXP4U+Tmtm3lj1k6kBlgeB42/NtAH
AACdTMPxXmuA+fiTrKHvuS+xFrYcbGj6SDa4uiUWV9WCU9AHAAAgAAAAq/tmzFGv
wmcIaYYgDxJidNRFk71JTjqUaKXS2wMuDVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAA=="/>

</HardDisk>

The KeyStore is encoded using Base64, and it contains the information needed by the machine to verify the password each time the user wants to start a machine or change its password.

I made a tool called VBOXDIECracker as a proof of concept to crack weak passwords used in this new feature of VirtualBox, you can download it from:

https://github.com/sinfocol/vboxdie-cracker/

Following is a detailed explanation of how this new feature works:

KeyStore Format

First, we need to identify in someway the fields within the decoded keystore:

0000h: 53 43 4E 45 00 01 41 45 53 2D 58 54 53 32 35 36  SCNE..AES-XTS256
0010h: 2D 50 4C 41 49 4E 36 34 00 00 00 00 00 00 00 00  -PLAIN64........
0020h: 00 00 00 00 00 00 50 42 4B 44 46 32 2D 53 48 41  ......PBKDF2-SHA
0030h: 32 35 36 00 00 00 00 00 00 00 00 00 00 00 00 00  256.............
0040h: 00 00 00 00 00 00 40 00 00 00 12 02 78 97 DA CB  ......@.....x—ÚË
0050h: 3A 4C 4F EE F4 87 62 9D 68 A0 73 00 20 D9 B5 DE  :LOîô‡b h s. ÙµÞ
0060h: 74 94 40 8C 7A F9 9A F0 82 89 20 00 00 00 27 B5  t”@Œzùšð‚‰ ...'µ
0070h: 01 C3 16 F4 9F C2 96 B2 FE 32 85 57 35 16 73 81  .Ã.ôŸÂ–²þ2…W5.s.
0080h: AC 20 9F D1 C0 C8 3E 5E 41 B6 6F F3 C3 5A D0 07  ¬ ŸÑÀÈ>^A¶oóÃZÐ.
0090h: 00 00 8A 8F 4A 94 83 7E EC 1B B4 D6 9A 2E 7C 9F  ..Š J”ƒ~ì.´Öš.|Ÿ
00A0h: FA DC 5E 65 95 36 DF 45 A8 1C 46 66 2C F6 6B E9  úÜ^e•6ßE¨.Ff,öké
00B0h: 5E 58 D0 07 00 00 40 00 00 00 EA A5 55 F2 73 AE  ^XÐ...@...ê¥Uòs®
00C0h: AF 9F 11 57 12 8F D1 C3 51 7D 7C AE F4 3E C9 AA  ¯Ÿ.W. ÑÃQ}|®ô>ɪ
00D0h: A5 40 69 17 CD 13 72 C5 76 8C F8 85 7C 56 59 67  ¥@i.Í.rÅvŒø…|VYg
00E0h: 31 8C E1 81 24 0F C1 43 95 6E C2 FA C3 C4 EF 0E  1Œá $.ÁC•nÂúÃÄï.
00F0h: 62 9C 18 82 5D F2 28 E7 1E C2                    bœ.‚]ò(ç.Â

After some work we are able to identify each field:

VirtualBox KeyStore File Format
Offset Bytes Description
0 4 File header signature = 0x454E4353 (SCNE)
4 2 Version
6 32 EVP algorithm
38 32 PBKDF2 hash algorithm
70 4 Generic key length (used by PBKDF2 and AES-XTS)
74 32 Final hash where comparison is done
106 4 Key length used in the second call to PBKDF2
110 32 Salt used in the second call to PBKDF2
142 4 Iterations used in the second call to PBKDF2
146 32 Salt used in the first call to PBKDF2
178 4 Iterations used in the first call to PBKDF2
182 4 EVP input length
186 64 Encrypted password used in the second call to PBKDF2 (to be used as input in the call to AES-XTS)

VirtualBox Keystore 010 editor template

The following 010 Editor template could be used as a guide:

//--------------------------------------
//--- 010 Editor v6.0.2 Binary Template
//
// File:        VBOXDIEKeyStore.bt
// Author:      Daniel Correa
// URL:         http://www.sinfocol.org/
// Revision:    1.0
// Purpose:     Template for VirtualBox Disk Image Encryption KeyStore
//--------------------------------------

typedef struct vbox_die_keystore {
    int header <bgcolor=0xaabbcc, format=hex, name="Header">;

    if (header != 0x454E4353) {
        SetBackColor(0x0000ff);
        Warning("File is not a valid VBOX DIE KeyStore. Bad signature.");
        return -1;
    }

    uint16 version <bgcolor=0xccddee, name="Version">;
    char algorithm[32] <bgcolor=0x00ffee, name="EVP encryption algorithm">;
    char kdf[32] <bgcolor=0xffbbee, name="Key derivation function hash algorithm">;
    int generic_key_length <bgcolor=0x3399ee, name="Generic key length">;
    char final_hash[32] <bgcolor=0x4444ff, name="Final hash">;
    int pbkdf2_2_key_length <bgcolor=0x3399ee, name="Second PBKDF2 key length">;
    char pbkdf2_2_salt[32] <bgcolor=0x999999, name="Second PBKDF2 salt">;
    int pbkdf2_2_iterations <bgcolor=0xaa9933, name="Second PBKDF2 iterations">;
    char pbkdf2_1_salt[32] <bgcolor=0x999999, name="First PBKDF2 salt">;
    int pbkdf2_1_iterations <bgcolor=0xaa9933, name="First PBKDF2 iterations">;
    int evp_decrypt_input_length <bgcolor=0x3399ee, name="EVP decrypt input length">;
    char pbkdf2_2_encrypted_password[64] <bgcolor=0xff7777, name="Second PBKDF2 encrypted password">;
};

FSeek(0);
LittleEndian();
vbox_die_keystore VBOXDIE;

The result of running the template:

VBOXDIE 010 editor template 1

VBOXDIE 010 editor template 2

VirtualBox password storage algorithm

With the identification of the fields within the keystore we can now have an understanding of how the password storage algorithm works, and it is summarized in this way:


# 32 for AES-XTS128-PLAIN64
# 64 for AES-XTS256-PLAIN64
AES_key_length = 32 | 64
-------------------------
AES-password = PBKDF2(algorithm: SHA256,
password: user_password,
salt: random_salt_1,
iterations: 2000,
output_length: AES_key_length)
----------------------------------------------
PBKDF2-decrypted-password = AES_decrypt(key_size: AES_key_length,
mode: XTS,
data: random_data
password: AES-password,
type: raw,
iv: NULL)
-------------------------------------
Stored_hash = PBKDF2(algorithm: SHA256,
password: PBKDF2-decrypted-password,
salt: random_salt_2,
iterations: 2000,
output_length: 32)

The same process is performed each time the user wants to decrypt the machine disk. The stored hash (the one from keystore) is compared with the computed hash (the one from user input) in order to authenticate the user and let him use the machine.

VBOXDIECracker - the tool

With the appropriate format and algorithm we can emulate the password verification of VirtualBox and make a not-so-fast cracker with PHP (sorry guys, I did not find a standard package on python to use AES XTS), it is just a proof of concept, so you can develop another leet tools.

You can download it from this site or browse it from the repository.

This is a sample of the source code showing the main function which is the one who computes the final hash:

<?php

// redacted

/**
 * crack_keystore
 *
 * Makes a bruteforce to find the final hash contained in the KeyStore
 * Returns the plaintext password used to encrypt de disk of the virtual machine
 */
function crack_keystore($keystore, $wordlist) {
    $fp = fopen($wordlist, 'r');
    if (is_resource($fp)) {
        $hash = get_hash_algorithm($keystore);
        $method = get_openssl_method($keystore);

        while (!feof($fp)) {
            $user_password = trim(fgets($fp));

            $EVP_password = hash_pbkdf2($hash, $user_password, $keystore['pbkdf2_1_salt'], $keystore['pbkdf2_1_iterations'], $keystore['generic_key_length'], true);

            $decrypted_password = openssl_decrypt(substr($keystore['pbkdf2_2_encrypted_password'], 0, $keystore['evp_decrypt_input_length']), $method, $EVP_password, OPENSSL_RAW_DATA, '');
            if ($decrypted_password === false) {
                continue;
            }

            $final_hash = hash_pbkdf2($hash, $decrypted_password, $keystore['pbkdf2_2_salt'], $keystore['pbkdf2_2_iterations'], $keystore['pbkdf2_2_key_length'], true);
            if ($final_hash === $keystore['final_hash']) {
                return $user_password;
            }
        }

        return false;
    } else {
        return false;
    }
}

// redacted

And the final output with a recovered password:

$ php VBOXDIECracker.php
VirtualBox Disk Image Encryption cracker

Usage: VBOXDIECracker.php disk_image.vbox [wordlist]

$ php VBOXDIECracker.php Encrypted.vbox wordlist.txt
VirtualBox Disk Image Encryption cracker

[+] Reading data from: Encrypted.vbox
----------------------------------------------------------------
[+] Checking hard disk encryption for: Encrypted.vdi
[+] Hard disk is encrypted
[+] KeyStore encoded string:
        U0NORQABQUVTLVhUUzI1Ni1QTEFJTjY0AAAAAAAAAAAAAAAAAABQQktERjItU0hB
        MjU2AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAASAniX2ss6TE/u9IdinWigcwAg2bXe
        dJRAjHr5mvCCiSAAAAAntQHDFvSfwpay/jKFVzUWc4GsIJ/RwMg+XkG2b/PDWtAH
        AACKj0qUg37sG7TWmi58n/rcXmWVNt9FqBxGZiz2a+leWNAHAABAAAAA6qVV8nOu
        r58RVxKP0cNRfXyu9D7JqqVAaRfNE3LFdoz4hXxWWWcxjOGBJA/BQ5VuwvrDxO8O
        YpwYgl3yKOcewg==
[+] KeyStore contents:
        Header                        454e4353 (SCNE)
        Version                       1
        Algorithm                     AES-XTS256-PLAIN64
        KDF                           PBKDF2-SHA256
        Key length                    64
        Final hash                    12027897dacb3a4c4feef487629d68a0730020d9b5de7494408c7af99af08289
        PBKDF2 2 Key length           32
        PBKDF2 2 Salt                 27b501c316f49fc296b2fe32855735167381ac209fd1c0c83e5e41b66ff3c35a
        PBKDF2 2 Iterations           2000
        PBKDF2 1 Salt                 8a8f4a94837eec1bb4d69a2e7c9ffadc5e659536df45a81c46662cf66be95e58
        PBKDF2 1 Iterations           2000
        EVP buffer length             64
        PBKDF2 2 encrypted password   eaa555f273aeaf9f1157128fd1c3517d7caef43ec9aaa5406917cd1372c5768c
                                      f8857c565967318ce181240fc143956ec2fac3c4ef0e629c18825df228e71ec2
[+] Cracking finished, measured time: 6.13035 seconds
[!] KeyStore password found: 123
----------------------------------------------------------------
[+] Checking hard disk encryption for: New_Disk.vdi
[-] Hard disk is not encrypted

Archivado en: Sin categoría |

3 comentarios

  1. john Octubre 10, 2015 @ 4:45 pm

    Great work!
    Guys like you make us safer, understanding not to use easy to crack methods.

    THANK YOU!

  2. Arthur Noviembre 3, 2015 @ 7:48 pm

    It seems to me that without a wordlist.txt or while using a complex password (that is not part of the wordlist.txt ) your tool won't work. Am I wrong ?

  3. JimF Diciembre 12, 2015 @ 5:45 pm

    This is now handled also by John ripper.

Deja un comentario