mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-22 08:08:10 +00:00
Improve anf fix bitwarden extract tool
This commit is contained in:
parent
6db32cd992
commit
b3f1a0ebdf
@ -50,50 +50,68 @@ def process_sqlite(path):
|
||||
key_hash = dataValue.split(b"keyHash")[1][9:53].decode()
|
||||
email = dataValue.split(b"email")[1][11:].split(b'\x00')[0].decode()
|
||||
iterations = int.from_bytes(dataValue.split(b"kdfIterations")[1][3:7], byteorder="little")
|
||||
|
||||
return email, key_hash, iterations
|
||||
|
||||
return [(email, key_hash, iterations)]
|
||||
|
||||
|
||||
def process_leveldb(path):
|
||||
try:
|
||||
import leveldb
|
||||
except ImportError:
|
||||
print("[WARNING] Please install the leveldb module for full functionality!\n", file=sys.stderr)
|
||||
return
|
||||
print("Please install the leveldb module for full functionality!\n", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
db = leveldb.LevelDB(path, create_if_missing=False)
|
||||
|
||||
try:
|
||||
active = db.Get(b'activeUserId').decode().strip('"')
|
||||
data = db.Get(active.encode())
|
||||
return process_json(data)
|
||||
out = []
|
||||
accIds = db.Get(b'authenticatedAccounts')
|
||||
accIds = json.loads(accIds)
|
||||
|
||||
for id in accIds:
|
||||
authAccData = db.Get(id.strip('"').encode())
|
||||
out.append(extract_json_profile(json.loads(authAccData)))
|
||||
|
||||
return out
|
||||
except(KeyError):
|
||||
# support for older Bitwarden versions (before account switch implementation)
|
||||
# data is stored in different format
|
||||
print("Failed to exctract data, trying old format.", file=sys.stderr)
|
||||
print("Failed to extract data, trying old format.", file=sys.stderr)
|
||||
email = db.Get(b'userEmail')\
|
||||
.decode("utf-8")\
|
||||
.strip('"').rstrip('"')
|
||||
.decode('utf-8')\
|
||||
.strip('"')
|
||||
key_hash = db.Get(b'keyHash')\
|
||||
.decode("ascii").strip('"').rstrip('"')
|
||||
.decode("ascii").strip('"')
|
||||
iterations = int(db.Get(b'kdfIterations').decode("ascii"))
|
||||
|
||||
return email, key_hash, iterations
|
||||
return [(email, key_hash, iterations)]
|
||||
|
||||
|
||||
def process_json(data):
|
||||
data = json.loads(data)
|
||||
|
||||
try:
|
||||
profile = data["profile"]
|
||||
email = profile["email"]
|
||||
iterations = profile["kdfIterations"]
|
||||
hash = profile["keyHash"]
|
||||
out = []
|
||||
accIds = data["authenticatedAccounts"]
|
||||
for id in accIds:
|
||||
authAccData = data[id.strip('"')]
|
||||
out.append(extract_json_profile(authAccData))
|
||||
|
||||
return out
|
||||
except(KeyError):
|
||||
print("Failed to exctract data, trying old format.", file=sys.stderr)
|
||||
print("Failed to extract data, trying old format.", file=sys.stderr)
|
||||
email = data["rememberedEmail"]
|
||||
hash = data["keyHash"]
|
||||
iterations = data["kdfIterations"]
|
||||
|
||||
return [(email, hash, iterations)]
|
||||
|
||||
|
||||
def extract_json_profile(data):
|
||||
profile = data["profile"]
|
||||
email = profile["email"]
|
||||
iterations = profile["kdfIterations"]
|
||||
hash = profile["keyHash"]
|
||||
return email, hash, iterations
|
||||
|
||||
|
||||
@ -101,15 +119,15 @@ def process_file(filename, legacy = False):
|
||||
try:
|
||||
if os.path.isdir(filename):
|
||||
# Chromium based
|
||||
email, key_hash, iterations = process_leveldb(filename)
|
||||
data = process_leveldb(filename)
|
||||
elif filename.endswith(".sqlite"):
|
||||
# Firefox
|
||||
email, key_hash, iterations = process_sqlite(filename)
|
||||
data = process_sqlite(filename)
|
||||
elif filename.endswith(".json"):
|
||||
# json - Desktop
|
||||
with open(filename, "rb") as f:
|
||||
data = f.read()
|
||||
email, key_hash, iterations = process_leveldb(data)
|
||||
data = process_json(data)
|
||||
else:
|
||||
print("Unknown storage. Don't know how to extract data.", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
@ -122,14 +140,14 @@ def process_file(filename, legacy = False):
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
if not email or not key_hash or not iterations:
|
||||
print("[error] %s could not be parsed properly!\nUser is probably logged out." % filename, file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
iterations2 = 1 if legacy else 2
|
||||
for entry in data:
|
||||
if len(entry) != 3:
|
||||
print("[error] %s could not be parsed properly!\nUser is probably logged out." % filename, file=sys.stderr)
|
||||
continue
|
||||
|
||||
print(f"$bitwarden$2*%d*%d*%s*%s\n" %
|
||||
(iterations, iterations2, base64.b64encode(email.encode("ascii")).decode("ascii"), key_hash))
|
||||
print("$bitwarden$2*%d*%d*%s*%s" %
|
||||
(entry[2], iterations2, base64.b64encode(entry[0].encode("ascii")).decode("ascii"), entry[1]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user