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! 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
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)
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" 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
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.
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
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
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:
hey, for anti-debug tricks have a look to this reference from Peter Ferrie http://pferrie.host22.com/papers/antidebug.pdf You'll find here most (if not all) anti-debug tricks, from easy ones to very complex tips.
@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).
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...
I'm currently working on "trusted storage"... I have written an device interface that read removable dev raw-sectors 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; } }