From 67ba1f21121e951e6d999a084842de4ee74ba164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=A0trom?= Date: Sun, 27 Feb 2022 23:29:15 +0100 Subject: [PATCH] add new version fix --- OpenCL/m23400-pure.cl | 25 +++++- src/modules/module_23400.c | 4 +- tools/bitwarden2hashcat.py | 143 +++++++++++++++++++++++++++++++++++ tools/test_modules/m23400.pm | 2 +- 4 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 tools/bitwarden2hashcat.py diff --git a/OpenCL/m23400-pure.cl b/OpenCL/m23400-pure.cl index 77baf0362..48480ed56 100644 --- a/OpenCL/m23400-pure.cl +++ b/OpenCL/m23400-pure.cl @@ -329,10 +329,27 @@ KERNEL_FQ void m23400_comp (KERN_ATTR_TMPS (bitwarden_tmp_t)) sha256_hmac_final (&sha256_hmac_ctx2); - const u32 r0 = sha256_hmac_ctx2.opad.h[0]; - const u32 r1 = sha256_hmac_ctx2.opad.h[1]; - const u32 r2 = sha256_hmac_ctx2.opad.h[2]; - const u32 r3 = sha256_hmac_ctx2.opad.h[3]; + sha256_hmac_ctx_t sha256_hmac_ctx3; + + + u32 buff[16] = {0}; + buff[0] = sha256_hmac_ctx2.opad.h[0]; + buff[1] = sha256_hmac_ctx2.opad.h[1]; + buff[2] = sha256_hmac_ctx2.opad.h[2]; + buff[3] = sha256_hmac_ctx2.opad.h[3]; + buff[4] = sha256_hmac_ctx2.opad.h[4]; + buff[5] = sha256_hmac_ctx2.opad.h[5]; + buff[6] = sha256_hmac_ctx2.opad.h[6]; + buff[7] = sha256_hmac_ctx2.opad.h[7]; + + sha256_hmac_init (&sha256_hmac_ctx3, out, 32); + sha256_hmac_update (&sha256_hmac_ctx3, buff, 32); + sha256_hmac_final (&sha256_hmac_ctx3); + + const u32 r0 = sha256_hmac_ctx2.opad.h[0] ^ sha256_hmac_ctx3.opad.h[0]; + const u32 r1 = sha256_hmac_ctx2.opad.h[1] ^ sha256_hmac_ctx3.opad.h[1]; + const u32 r2 = sha256_hmac_ctx2.opad.h[2] ^ sha256_hmac_ctx3.opad.h[2]; + const u32 r3 = sha256_hmac_ctx2.opad.h[3] ^ sha256_hmac_ctx3.opad.h[3]; #define il_pos 0 diff --git a/src/modules/module_23400.c b/src/modules/module_23400.c index 3704ef228..3a69b5d57 100644 --- a/src/modules/module_23400.c +++ b/src/modules/module_23400.c @@ -23,8 +23,8 @@ static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; -static const char *ST_PASS = "hashcat"; -static const char *ST_HASH = "$bitwarden$1*100000*bm9yZXBseUBoYXNoY2F0Lm5ldA==*zAXL7noQxkIJG82vWuqyDsnoqnKAVU7gE/8IRI6BlMs="; +static const char *ST_PASS = "hashcat1"; +static const char *ST_HASH = "$bitwarden$1*100000*bm9yZXBseUBoYXNoY2F0Lm5ldA==*CWCy4KZEEw1W92qB7xfLRNoJpepTMSyr7WJGZ0/Xr8c="; u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; } u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; } diff --git a/tools/bitwarden2hashcat.py b/tools/bitwarden2hashcat.py new file mode 100644 index 000000000..05d7932e1 --- /dev/null +++ b/tools/bitwarden2hashcat.py @@ -0,0 +1,143 @@ +"""Utility to extract Bitwarden data from Google Chrome / Firefox / Android local data""" + +# Based on bitwarden2john.py https://github.com/willstruggle/john/blob/master/bitwarden2john.py + +from dataclasses import dataclass +import os +import argparse +import string +import sys +import base64 +import binascii +import traceback +import xml.etree.ElementTree as ET +from dataclasses import dataclass + +try: + import json + assert json +except ImportError: + try: + import simplejson as json + except ImportError: + sys.stderr.write("Please install json module which is currently not installed.\n") + sys.exit(-1) + +try: + import leveldb +except ImportError: + sys.stderr.write("[WARNING] Please install the leveldb module for full functionality!\n") + sys.exit(-1) + + +@dataclass +class BitwardenData: + email: string + enc_key: string + key_hash: string + iterations: int = 0 + + +def process_xml_file(filename): + tree = ET.parse(filename) + root = tree.getroot() + email = None + enc_key = None + + for item in root: + if item.tag == 'string': + name = item.attrib['name'] + if name == "encKey": + enc_key = item.text + if name == "email": + email = item.text + return email, enc_key + + +def process_leveldb(path): + db = leveldb.LevelDB(path, create_if_missing=False) + + for key, value in db.RangeIter(): + print(key.decode('ascii').strip('"') + " " + value.decode('ascii').strip('"')) + + data = BitwardenData( + email = db.Get(b'userEmail')\ + .decode("utf-8")\ + .strip('"').rstrip('"'), + enc_key = db.Get(b'encKey')\ + .decode("ascii").strip('"').rstrip('"'), + key_hash = db.Get(b'keyHash')\ + .decode("ascii").strip('"').rstrip('"'), + # Usually 100000 + iterations = int(db.Get(b'kdfIterations').decode("ascii")) + ) + + print(data) + + return data + + +def process_file(filename): + if "nngceckbap" in filename or os.path.isdir(filename): + try: + bitw_data = process_leveldb(filename) + if not bitw_data.email or not bitw_data.enc_key: + sys.stderr.write("[error] %s could not be parsed properly!\n" % filename) + return + except: + traceback.print_exc() + return + else: + with open(filename, "rb") as f: + data = f.read() + if filename.endswith(".xml") or data.startswith(b"\n" % + # sys.argv[0]) + # sys.exit(-1) + + for p in args.path: + process_file(p) diff --git a/tools/test_modules/m23400.pm b/tools/test_modules/m23400.pm index 0981b0db0..4fd327845 100644 --- a/tools/test_modules/m23400.pm +++ b/tools/test_modules/m23400.pm @@ -29,7 +29,7 @@ sub module_generate_hash my $kdf2 = Crypt::PBKDF2->new ( hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256), - iterations => 1, + iterations => 2, output_len => 32 );