libyal / libbde

Library and tools to access the BitLocker Drive Encryption (BDE) encrypted volumes
GNU Lesser General Public License v3.0
214 stars 52 forks source link

How to use libbde_volume_open? #28

Closed uxctx closed 5 years ago

uxctx commented 6 years ago

about libbde_volume_open ,what is the filename parameter,

const char *filename="F:\\";
    result = libbde_volume_open(
        volume,
        filename,
        LIBBDE_OPEN_READ,
        &error);    
    if (result != 1) {
        libbde_error_fprint(error, stderr);
        libbde_error_free(&error);
        return 0;
    }

been failing,libbde_volume_open: unable to set filename in file IO handle.

joachimmetz commented 6 years ago

"F:\" is not a path of a file but the root of the volume with drive letter F: you'll need to point libbde_volume_open to a file.

uxctx commented 6 years ago
        libbde_volume_t *volume = NULL;
    libbde_error_t *error = NULL;
    int result = 0;

    result = libbde_volume_initialize(&volume, &error);
    if (result != 1) {
        libbde_error_fprint(error,stderr);
        libbde_error_free(&error);
        return 0;
    }

    unsigned char pasw[256];
    memcpy(pasw,"Dark123123",10);
    result = libbde_volume_set_utf8_password(volume,
        pasw,
        10,
        &error);
    if (result != 1) {
        libbde_error_fprint(error, stderr);
        libbde_error_free(&error);
        return 0;
    }

    int codepage = 0;
    libbde_get_codepage(&codepage, &error);

    const char *filename="F:\\123.txt";
    result = libbde_volume_open(
        volume,
        filename,
        LIBBDE_OPEN_READ,
        &error);    
    if (result != 1) {
        libbde_error_fprint(error, stderr);
        libbde_error_free(&error);
        return 0;
    }

this my code,I want to decrypt the F drive letter,traversing directory and read file, I don't know where to find the demo code,please help me,

uxctx commented 6 years ago

error string:libbde_volume_open: unable to open volume: F:\123.txt. but F:\123.txt It exists,f is an BitLocker disk

joachimmetz commented 6 years ago
  1. you'll need to point it to a valid BitLocker volume image file
  2. reading a live device with libbde is not recommend
  3. if you want to read from a device on Windows then use the correct path of the volume device \\.\F:
  4. you'll likely need to use libsmdev (or equiv) to read the device seeing Windows device files do not behave the same as normal files
uxctx commented 6 years ago

i am sorry pal, I didn't understand a lot of things. “volume image file” how to create,I have a USB flash disk,is ntfs,using BitLocker encryption,how to use libbde decryption,(>﹏<)

joachimmetz commented 6 years ago

libbde is intended for use in the context of digital forensic analysis.

a “volume image file” is a copy of the data of the volume copied into a file (https://whatis.techtarget.com/definition/forensic-image)

libbde supports the BitLocker format. It does not support reading from Windows volume devices directly. If you're not familiar with how to use volume device files on Windows I opt to use Linux instead.

I have a USB flash disk,is ntfs,using BitLocker encryption

Can you be more specific what is ntfs? is this BitLocker ToGo or did you unlock the BitLocker volume via the operating system?

how to use libbde decryption

Your code in the right direction you'll only have to provide libbde with input it understands / can handle.

I don't know where to find the demo code,please help me,

Check the bdetools like bdeinfo and bdemount. Also if you just want to unlock the volume why don't you use those tools instead?

uxctx commented 6 years ago

very sorry, there is now a F drive, which is encrypted,not unlocked,I am now trying to clone the encrypted disk into a mirrored file, let libbde understand this input,

const char *filename="D:\\IMAGE\\F.img";
    result = libbde_volume_open(
        volume,
        filename,
        LIBBDE_OPEN_READ,
        &error);    

result is still a failure, I just want to be on windows,use libbde to decrypt the drive letter encrypted by bitlocker,

joachimmetz commented 6 years ago

result is still a failure,

what is the error?

uxctx commented 6 years ago

Is insufficient memory,blocking in libbde_volume_open,I don't know what to do,

joachimmetz commented 6 years ago

@lucpp can you provide me with the error backtrace

uxctx commented 6 years ago
    libbde.dll!libbde_password_calculate_key(const unsigned char * password_hash, unsigned int password_hash_size, const unsigned char * salt, unsigned int salt_size, unsigned char * key, unsigned int key_size, int * * error)  476  C
    libbde.dll!libbde_metadata_read_volume_master_key(libbde_metadata * metadata, libbde_io_handle * io_handle, libbde_password_keep * password_keep, const unsigned char * external_key, unsigned int external_key_size, unsigned char * volume_master_key, unsigned int volume_master_key_size, int * * error) 行2180  C
    libbde.dll!libbde_volume_open_read_keys_from_metadata(libbde_internal_volume * internal_volume, libbde_metadata * metadata, int * * error)  1700    C
    libbde.dll!libbde_volume_open_read(libbde_internal_volume * internal_volume, int * file_io_handle, int * * error)  1371 C
    libbde.dll!libbde_volume_open_file_io_handle(int * volume, int * file_io_handle, int access_flags, int * * error)  825  C
    libbde.dll!libbde_volume_open(int * volume, const char * filename, int access_flags, int * * error)  428    C
    bderun.exe!main(int argc, char * * argv)  58    

the above is the stack when libbde_volume_open is blocked,it seems normal,

I tried to make the disk image file small enough,this maybe reduce blocking time and memory usage,

so I made a 50M image file,but the memory footprint is still very high,The good news is that the final call to libbde_volume_open is successful.,But I still don't know if the data output by libbde_volume_read_buffer is correct,i am trying to test....

another question is, when the password set by libbde_volume_set_utf8_password is wrong, Libbde_volume_open will always be blocked, memory usage will continue to skyrocket, it seems that it will not stop at all~

joachimmetz commented 6 years ago

but the memory footprint is still very high

What is very high in you perspective? Please provide an order of magnitude.

Libbde_volume_open will always be blocked, memory usage will continue to skyrocket, it seems that it will not stop at all~

Are you using Windows Crypto API or did you define WINVER=0x501 ? Also see: https://github.com/libyal/libcaes/issues/1

uxctx commented 6 years ago

my computer uses win10 system,and use win10 sdk, HAVE_WINCRYPT 1 WINVER >= 0x0600 I think it should use the Windows Crypto API,so need to disable the use of the Windows Crypto API, and using openssl?

about memory usage,I made a 50M disk image file,in the process of blocking libbde_volume_open, more than 600M of memory is used,it takes a long time to use````

    //const char *filename="D:\\IMAGE\\G.img";

    clock_t start, finish;
    double total_time;
    start = clock();

    result = libbde_volume_open(
        volume,
        filename,
        LIBBDE_OPEN_READ,
        &error);    
    if (result != 1) {
        libbde_error_fprint(error, stderr);
        libbde_error_free(&error);
        return 0;
    }

    finish = clock();
    total_time = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("%f seconds\n", total_time);
>>>>>
124.637000 seconds  vvery long
uxctx commented 6 years ago

Just now, I tried to disable the Windows Crypto API, using OpenSSL, but the memory footprint is still the same, ≈604M, and libbde_volume_open blocked for a longer time, taking about 153 seconds~~~

153.282000 seconds

maybe my disk image is wrong?I am very confused,

joachimmetz commented 6 years ago

If you can open the disk image and see a file system the image and libbde are working. When time permits I'll have a look to see if I can reproduce the time to open and memory usage. A known issue is a long time to open when using WinCrypt.

uxctx commented 6 years ago
     libbde_volume_open
    …………

    FILE* output = fopen("new_image.img", "wb");
    …………

    char *buffer=(char*)malloc(1024 * 1024);
    ssize_t size=
    libbde_volume_read_buffer(volume, buffer, 1024 * 1024, &error);
    while (size > 0) {
        fwrite(buffer, size,1,output);
        size =
            libbde_volume_read_buffer(volume, buffer, 1024 * 1024, &error);
    }
    //libbde_volume_seek_offset()
    free(buffer);
    fflush(output);
    fclose(output);

after test,new_image.img is indeed the decrypted disk content,the entire process seems to be successful…… But I don't understand,why use so much memory and use so much time? I feel that it is not the reason why WinCrypt is slow,because using almost the same memory when using openssl, and it takes longer to use, I guess the libbde_password_calculate_key function has the possibility of redundant loops under Windows,of course, this is just my guess. I don’t understand the algorithm flow of decryption.

joachimmetz commented 6 years ago

But I don't understand,why use so much memory and use so much time? I guess the libbde_password_calculate_key function has the possibility of redundant loops under Windows

No, a minimum number of iterations is needed (for cryptographic purposes).

I don’t understand the algorithm flow of decryption.

I recommend to learn about it before you make speculations.

But I don't understand,why use so much memory and use so much time?

As previously indicated: That the current usage of WinCrypt is slow is something that needs a closer look feel free to find out why and let me know, my available time is limited.

Regarding memory usage I'll have a look when time permits. Might be just a matter of tuning the maximum size of the internal caches.

uxctx commented 6 years ago
**libbde/libbde_password.c line 344  [libbde_password_calculate_key]**
-------------------------------------------------------------------------------------
int libbde_password_calculate_key(
     const uint8_t *password_hash,
     size_t password_hash_size,
     const uint8_t *salt,
     size_t salt_size,
     uint8_t *key,
     size_t key_size,
     libcerror_error_t **error )
{
    libbde_password_key_data_t password_key_data;

    static char *function = "libbde_password_calculate_key";

    ……………………
    /* The password key is the SHA256 digest hash after 0x100000 key iterations
     */
    for( password_key_data.iteration_count = 0;
         password_key_data.iteration_count < 0x000fffffUL;
         password_key_data.iteration_count += 1 )
    {
        if( libhmac_sha256_calculate(
             (uint8_t *) &password_key_data,
             sizeof( libbde_password_key_data_t ),
             password_key_data.last_sha256_hash,
             LIBHMAC_SHA256_HASH_SIZE,
             error ) != 1 )
        {
            libcerror_error_set(
             error,
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
             "%s: unable to calculate SHA256.",
             function );

            return( -1 );
        }
    }
    …………………
    return( 1 );
}
libbde/libbde_password.c line 344  [libbde_password_calculate_key]
call stack>>>>>>>
    libbde.dll!libbde_password_calculate_key(const unsigned char * password_hash, unsigned int password_hash_size, const unsigned char * salt, unsigned int salt_size, unsigned char * key, unsigned int key_size, int * * error)  476  C
    libbde.dll!libbde_metadata_read_volume_master_key(libbde_metadata * metadata, libbde_io_handle * io_handle, libbde_password_keep * password_keep, const unsigned char * external_key, unsigned int external_key_size, unsigned char * volume_master_key, unsigned int volume_master_key_size, int * * error) 2180   C
    libbde.dll!libbde_volume_open_read_keys_from_metadata(libbde_internal_volume * internal_volume, libbde_metadata * metadata, int * * error)  1700    C
    libbde.dll!libbde_volume_open_read(libbde_internal_volume * internal_volume, int * file_io_handle, int * * error)  1371 C
    libbde.dll!libbde_volume_open_file_io_handle(int * volume, int * file_io_handle, int access_flags, int * * error)  825  C
    libbde.dll!libbde_volume_open(int * volume, const char * filename, int access_flags, int * * error)  428    C

Always executing this for loop,until 【password_key_data.iteration_count >= 0x000fffffUL】

for(
password_key_data.iteration_count = 0; 
password_key_data.iteration_count < 0x000fffffUL;
password_key_data.iteration_count += 1 )

In the segment code, memory usage continues to grow, and the execution time takes about two minutes!I feel this is not normal……

I am using the package libbde-alpha-20170902.tar.gz

joachimmetz commented 5 years ago

duplicate of the wincrypt issue https://github.com/libyal/libbde/issues/21