-
-
Save HarmJ0y/116fa1b559372804877e604d7d367bbc to your computer and use it in GitHub Desktop.
#!/usr/bin/python | |
# Python port of keepass2john from the John the Ripper suite (http://www.openwall.com/john/) | |
# ./keepass2john.c was written by Dhiru Kholia <dhiru.kholia at gmail.com> in March of 2012 | |
# ./keepass2john.c was released under the GNU General Public License | |
# source keepass2john.c source code from: http://fossies.org/linux/john/src/keepass2john.c | |
# | |
# Python port by @harmj0y, GNU General Public License | |
# | |
# TODO: handle keyfiles, test file inlining for 1.X databases, database version sanity check for 1.X | |
# | |
import sys | |
import os | |
import struct | |
from binascii import hexlify | |
def process_1x_database(data, databaseName, maxInlineSize=1024): | |
index = 8 | |
algorithm = -1 | |
encFlag = struct.unpack("<L", data[index:index+4])[0] | |
index += 4 | |
if (encFlag & 2 == 2): | |
# AES | |
algorithm = 0 | |
elif (enc_flag & 8): | |
# Twofish | |
algorithm = 1 | |
else: | |
print "Unsupported file encryption!" | |
return | |
# TODO: keyfile processing | |
# TODO: database version checking | |
version = hexlify(data[index:index+4]) | |
index += 4 | |
finalRandomseed = hexlify(data[index:index+16]) | |
index += 16 | |
encIV = hexlify(data[index:index+16]) | |
index += 16 | |
numGroups = struct.unpack("<L", data[index:index+4])[0] | |
index += 4 | |
numEntries = struct.unpack("<L", data[index:index+4])[0] | |
index += 4 | |
contentsHash = hexlify(data[index:index+32]) | |
index += 32 | |
transfRandomseed = hexlify(data[index:index+32]) | |
index += 32 | |
keyTransfRounds = struct.unpack("<L", data[index:index+4])[0] | |
filesize = len(data) | |
datasize = filesize - 124 | |
if((filesize + datasize) < maxInlineSize): | |
dataBuffer = hexlify(data[124:]) | |
end = "*1*%ld*%s" %(datasize, hexlify(dataBuffer)) | |
else: | |
end = "0*%s" %(databaseName) | |
return "%s:$keepass$*1*%s*%s*%s*%s*%s*%s*%s" %(databaseName, keyTransfRounds, algorithm, finalRandomseed, transfRandomseed, encIV, contentsHash, end) | |
def process_2x_database(data, databaseName): | |
index = 12 | |
endReached = False | |
masterSeed = '' | |
transformSeed = '' | |
transformRounds = 0 | |
initializationVectors = '' | |
expectedStartBytes = '' | |
while endReached == False: | |
btFieldID = struct.unpack("B", data[index])[0] | |
index += 1 | |
uSize = struct.unpack("H", data[index:index+2])[0] | |
index += 2 | |
# print "btFieldID : %s , uSize : %s" %(btFieldID, uSize) | |
if btFieldID == 0: | |
endReached = True | |
if btFieldID == 4: | |
masterSeed = hexlify(data[index:index+uSize]) | |
if btFieldID == 5: | |
transformSeed = hexlify(data[index:index+uSize]) | |
if btFieldID == 6: | |
transformRounds = struct.unpack("H", data[index:index+2])[0] | |
if btFieldID == 7: | |
initializationVectors = hexlify(data[index:index+uSize]) | |
if btFieldID == 9: | |
expectedStartBytes = hexlify(data[index:index+uSize]) | |
index += uSize | |
dataStartOffset = index | |
firstEncryptedBytes = hexlify(data[index:index+32]) | |
return "%s:$keepass$*2*%s*%s*%s*%s*%s*%s*%s" %(databaseName, transformRounds, dataStartOffset, masterSeed, transformSeed, initializationVectors, expectedStartBytes, firstEncryptedBytes) | |
def process_database(filename): | |
f = open(filename, 'rb') | |
data = f.read() | |
f.close() | |
base = os.path.basename(filename) | |
databaseName = os.path.splitext(base)[0] | |
fileSignature = hexlify(data[0:8]) | |
if(fileSignature == '03d9a29a67fb4bb5'): | |
# "2.X" | |
print process_2x_database(data, databaseName) | |
elif(fileSignature == '03d9a29a66fb4bb5'): | |
# "2.X pre release" | |
print process_2x_database(data, databaseName) | |
elif(fileSignature == '03d9a29a65fb4bb5'): | |
# "1.X" | |
print process_1x_database(data, databaseName) | |
else: | |
print "ERROR: KeePass signaure unrecognized" | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
sys.stderr.write("Usage: %s <kdb[x] file[s]>\n" % sys.argv[0]) | |
sys.exit(-1) | |
for i in range(1, len(sys.argv)): | |
process_database(sys.argv[i]) |
@KingAlex1985, place database near this file and run python keepass2john.py database_name.kdbx
Getting error Keepass signature unrecognized on 2.29 file
Is there an update for this?
Traceback (most recent call last):
File "keepass2john.py", line 149, in <module>
process_database(sys.argv[i])
File "keepass2john.py", line 130, in process_database
print process_2x_database(data, databaseName)
File "keepass2john.py", line 85, in process_2x_database
btFieldID = struct.unpack("B", data[index])[0]
IndexError: string index out of range
just doesn't work (keepass 2.5.4)
Traceback (most recent call last): File "keepass2john.py", line 150, in <module> process_database(sys.argv[i]) File "keepass2john.py", line 131, in process_database print process_2x_database(data, databaseName) File "keepass2john.py", line 86, in process_2x_database btFieldID = struct.unpack("B", data[index])[0] IndexError: string index out of range
Not working with keepassxc 2.6.2
It has a double hexlify. end = "1%ld*%s" %(datasize, hexlify(dataBuffer)) should be end = "1%ld*%s" %(datasize, dataBuffer) If your cracking keepass 1's change this.
as for the others with exceptions, those are probably keepasses with keyfiles, they're not supported.
Is there any documentation / description how to use this script?
I know Java but not Python.
Sorry for asking. :-)