[c++] Truecrypt: Inject DLL (Software Token)

Discussion in 'Mixed Languages' started by deagles, May 29, 2013.

  1. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    #1 deagles, May 29, 2013
    Last edited by a moderator: Apr 20, 2017
    I think I don't need to explain that Truecrypt is one of the leading encryption tools.

    To improve the security Truecrypt supports Two Factor Authentication (PKCS#11 Hardware Token),
    but Hardware Tokens are expensive and normally not sold to single-users.

    Truecrypt also supports simple keyfiles which can be stored on usb storage.
    The big disadvantage is that keyfiles are not protected.

    Software tokens create a trusted storage to protect keyfiles.
    My goal is to create a software token by injecting a dll into truecrypt and store a encrypted keyfile on usb.

    I already created a dll and hooked:
    Code:
    BOOL _cdecl KeyFileProcess (/*unsigned __int8 *keyPool,*/ KeyFile *keyFile);
    
    This function is used to read a keyfile into memory and combine it with the keyPool.
    At this point I want to add a new security layer around the keyfile.

    I implemented a simple xor stream-encryption and it works! :biggrin:
    Next I want to create a trusted storage inside the "keyfile" that is written to hard drive.

    For performance reasons a byte-stream-cipher is preferred.

    I want to know how you would implement one of the following:

    - Trusted Store (improve security, detect changes, limit the number of attempts)
    - Encryption layer
    - Code Integrity (verify dll)
    - USB hardware binding (combine usb serial + hardware hash ?)
    - Detect debugger / VM

    All ideas are welcomed :idea:
     
  2. Humphrey

    Humphrey MDL Expert

    Dec 13, 2011
    1,458
    981
    60
    #2 Humphrey, May 29, 2013
    Last edited: May 29, 2013
    Seen this video, will your changes solve for this: https://www.youtube.com/watch?v=BbcEnrZiftQ


    Currently I am using TrueCrypt with a password and keypass with a key file on a encrypted USB (encrypted with truecrypt)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    #3 deagles, May 29, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    This attack is possible if your pc is running, the volume is currently mounted and the attacker has physically access.

    The truecrypt driver needs to know what the password is ;)

    But it's more often the case that "attackers" :cool: of truecrypt volumes attack unmounted volumes.

    Truecrypt internally uses a crc stream hash:
    Code:
    #define KEYFILE_POOL_SIZE 64
    static unsigned __int8 keyPool [KEYFILE_POOL_SIZE];
    
    => BaseAddress + static offset = keyPool

    The last inserted password is also available at a static address:

    => BaseAddress + static offset = last inserted password (atleast I can access it in my hook function, maybe burned later on)

    It should be clear that a running computer with mounted volumes is unsafe.
    In case of need disconnect power!

    My dll could help because it would be impossible to mount the volume before the dll is injected and correct pin is entered.
    The whole world knows TrueCrypt but who knows my custom DLL :renske:
     
  4. user_hidden

    user_hidden MDL Expert

    Dec 18, 2007
    1,026
    973
    60
    I would normally agree but now a days there are people reposting mdl tools around the internet so your custom dll will make it into the wild. :eek:
     
  5. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    Thats no problem we can use strong encryption.
    I think storing keyfiles on usb and decrypting them in memory is more secure than just storing the keyfile.

    I would like to make a good concept and learn more about protecting memory / processes and other cool techniques to create a useful truecrypt addon :)
     
  6. woot332

    woot332 MDL Senior Member

    Feb 18, 2011
    390
    807
    10
    #6 woot332, May 30, 2013
    Last edited: May 30, 2013
    As for anti debugger tricks and vm detection theres written a lot about it.
    Also maybe running a couple of "protection" threads would work for enforcing
    memory and process integrity. Anyways those are just some ideas and
    there might be some eaiser and better ways of doing it.:)

    anti debugger tricks:
    http://tuts4you.com/download.php?list.66
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    I thought of different concepts to enter / verify decryption password.
    And of course you all know keylogger... (replay attacks)

    I think one-time passwords are the very best solution to protect the tokens keyfile,
    there is a neat technique called challenge response authentication.

    I designed a 8x8 matrix (base64 charset), perform random permutations and print the matrix. (challenge)
    Now the user needs a shared secret with the programm (stored), similar to android you keep a path not a alpha numeric password ;)
    You follow your key-path and enter all characters along.
    The program revert the entered pin back to path coords then hash it so it can be verified.

    StoredKey = Hash(Salt2 + Hash(Salt1 + Path)),
    Keyfile DecryptKey = Hash(Salt2 + Path)

    - Two Factor Authentication (password + token)
    - Protect Keyfile (encrypted)
    - One time password

    My current gui design:

    [​IMG]
     
  8. Humphrey

    Humphrey MDL Expert

    Dec 13, 2011
    1,458
    981
    60
    Could you make truecrypt work with finger print scanners or maybe picture passwords?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. Pr3acher

    Pr3acher MDL Member

    Aug 24, 2012
    142
    48
    10
  10. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    @Pr3acher: Thanks this paper looks very professional.

    Yes it's possible... I can directly modify truecrypts keyPool before it's passed to truecrypts driver.
    In general all constant data could be used for authentication (picture passwords -> math algorithm to add tolerance for mouse gestures).
     
  11. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    I'm little stuck with proper authentication.
    My previous concept of path challenge-response auth is not enough.
    It protects for hardware keyloggers but most of software keyloggers are able to capture the screen.

    If the attacker know the concept and if he can capture one successful attempt the protection is broken.
    I read this paper and the only solution is to add redundancy to the challenge (Figure 7).
    But to make this work the dll needs to know the plaintext password (shared secret),
    not possible to store a hash...
     
  12. deagles

    deagles MDL Developer

    Feb 22, 2013
    239
    1,174
    10
    #12 deagles, Jun 8, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    I'm currently working on "trusted storage"...
    I have written an device interface that read removable dev raw-sectors :cool:

    Now the plan is to get a free cluster, mark it in FAT as used and write the encrypted token key to that cluster.
    Windows and all other programs will not recognize raw data.

    Here are my structs:

    Code:
    
        // Token Table (512byte)
        typedef struct TOKEN_TABLE {
            BYTE IV[16]; // Random IV
            // Encryption start
            // ...
            BYTE INVOLUTION[256]; // Random self-inverse permutation
            BYTE KEY_IV[16]; // Random KEY_IV
            BYTE USBSERIAL[32]; // Usb serial SHA256 hash
            BYTE AESMAC[16]; // AES CBC-MAC
            // Encryption end
        } TOKEN_TABLE;
    
        // Token Key (512byte)
        typedef struct TOKEN_KEY {
            // Encryption start
            BYTE KEY[479]; // Random token key
            BYTE SHA256[32]; // SHA256 hash
            BYTE PAD; // must be 0xAA
            // Encryption end
        } TOKEN_KEY;
    
    
    1) Create TOKEN_KEY struct
    2) Create TOKEN_TABLE struct
    3) Self inverse permutation (TOKEN_KEY)
    4) Encrypt TOKEN_KEY with user pin + KEY_IV
    5) AESMAC authenticated encryption
    6) Encrypt TOKEN_TABLE part with userpin + IV

    Create random self-inverse permutation (SBox):

    f²(x) = x

    Code:
    
    // Random permutation (p = 1 / n!)
    // Fisher-Yates shuffle (Knuth shuffle)
    __forceinline VOID random_permutation(PBYTE const finite_set, size_t const cardinality)
    {
        BYTE bTmp;
    
        srand(GetTickCount());
    
        for(DWORD i = cardinality - 1, r; i > 0; i--)
        {
            r = rand() % (i + 1);
            bTmp = finite_set;
            finite_set = finite_set[r];
            finite_set[r] = bTmp;
        }
    }
    
    // GF(8) Involution
    // Based on Fisher-Yates shuffle (Knuth shuffle)
    // Requires a ordered finite-set of GF(8)
    __forceinline VOID GF_Involution(PBYTE const finite_set)
    {
        BYTE bTmp;
    
        size_t const cardinality = 256;
    
        srand(GetTickCount());
    
        for(DWORD i = cardinality - 1, r; i > 0; i--)
        {
            // Edit: Iterate to previous fixpoint
            for(; finite_set != i; i--)
                if(i == 0) return; // No more cycles, exit here to prevent infinite loop
    
            // Edit: Do not allow fixpoints
            r = rand() % i;
    
            // Edit: Iterate to next fixpoint
            for(; finite_set[r] != r; r = (r + 1) % i);
    
            bTmp = finite_set;
            finite_set = finite_set[r];
            finite_set[r] = bTmp;
        }
    }
    
    
     
  13. Humphrey

    Humphrey MDL Expert

    Dec 13, 2011
    1,458
    981
    60
    If I knew jack about C++ I would help. :(
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...