TrueCrypt Self-Bruteforce
Last Updated on Wednesday, 25 August 2010 20:54
Monday, 15 March 2010 00:00
In the last weeks I was playing with many of the challengues of Yashira (If you don't know it, I recommend you to take a look over it as it is one of the biggest spanish web of wargames AFIK) and one of the challenge was to crack a TrueCrypt file. I knew about the existence of that application but I never used it... until now.
So I decided to download TrueCrypt and play around with the program to get familiar with it. After read the documentation and some reviews I realize that it is a very secure piece of software that implements many high level features so I knew I will not be easy, at least in theory.
I start to search in internet for some tools than can help me to bruteforce the file but I couldn't find any. I remember one page propose one solution: Create an script and launch the truecrypt aplication with some command line options and test if was possible to open it. I tried to do it but it was really slow so I start to search for another options until I found a way to use truecrypt as a self-bruteforce: Instead of launch truecrypt everytime with a different password I made a script in python with the winappdbg python module that acts as a loader and change/test the password in the memory space of truecrypt itself.
Requirementes and notes:
- python 2.6.4 (2.6.x should also work)
- winappdbg-1.3.win32
- Use the truecrypt application provided in the attached file or against a Keepass version 6.3a
- It only works agains volumes without keyfiles
TrueCrypt Self-Bruteforce Python Code
# TrueCrypt Self-Bruteforce v0.1
# Based in Truecrypt version 6.3a
# Programmed by Miguel Febres
# mafebresv at q-protex.com
# http://www.q-protex.com
# Performance: 2 words per second (Core Duo 2.2GHZ), DeviceIoControl is slow
from winappdbg import Debug
from time import strftime
import time
counter=0
word=""
words=[]
r_eax = 0
r_ecx = 0
r_edx = 0
ptrBuffer=0
WORD_SIZE = 20
def action_2( event ):
global word
global counter
global debug
global ptrBuffer
global WORD_SIZE
aThread = event.get_thread()
aProcess = event.get_process()
if aProcess.peek(ptrBuffer, 1) == '\x00':
print 'Counter: ' + repr(counter) + ' - Correct: ' + word
debug.dont_break_at(aProcess.get_pid() , 0x0043F93E)
else:
#if (counter%1000)==0:
print 'Counter: ' + repr(counter) + ' - Incorrect: ' + word
if counter< len(words):
aProcess.poke(ptrBuffer, '\x00') #flag 1
word=words[counter]
word = word.replace("\n","")
word = word[0:WORD_SIZE-1]
#word = word.lower() #optional
word = word.ljust(WORD_SIZE,"\0")
aProcess.poke_uint(ptrBuffer + 0x218, WORD_SIZE)
aProcess.poke(ptrBuffer + 0x21C, word)
aThread.set_register("Eip", 0x0043F90F)
aThread.set_register("Eax",r_eax)
aThread.set_register("Ecx",r_ecx)
aThread.set_register("Edx",r_edx)
counter+=1
else:
aProcess.kill()
def action_1( event ):
global debug
global ptrBuffer
aThread = event.get_thread()
aProcess = event.get_process()
ptrBuffer = aThread.get_register("Ecx")
debug.dont_break_at(aProcess.get_pid() , 0x0043F929)
def action_0( event ):
global debug
aThread = event.get_thread()
aProcess = event.get_process()
r_eax = aThread.get_register("Eax")
r_ecx = aThread.get_register("Ecx")
r_edx = aThread.get_register("Edx")
debug.dont_break_at(aProcess.get_pid() , 0x0043F90F)
words = open('dic.txt', "r").readlines() #lengthall
print "[+] Words Loaded:",len(words)
try:
debug = Debug()
# Start a new process for debugging
p = debug.execv( ['TrueCrypt.exe', '/v', 'test.tc', '/lx', '/p', "".ljust(WORD_SIZE) ,'/q', '/s'])
debug.break_at(p.get_pid() , 0x0043F90F, action_0) #save state
debug.break_at(p.get_pid() , 0x0043F929, action_1) #save buffer addres
debug.break_at(p.get_pid() , 0x0043F93E, action_2) #check result, restore state, change eip
# Wait for the debugee to finish
t1 = time.clock()
debug.loop()
finally:
debug.stop()
print 'Finished in ' + repr(time.clock() - t1) + ' seconds!'
Of course, to made this script possible first I debug keepass and after a while I found how to change the password in memory and force the program to test it again.