mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-31 19:08:43 +00:00
add new version fix
This commit is contained in:
parent
5df0adc113
commit
67ba1f2112
@ -329,10 +329,27 @@ KERNEL_FQ void m23400_comp (KERN_ATTR_TMPS (bitwarden_tmp_t))
|
|||||||
|
|
||||||
sha256_hmac_final (&sha256_hmac_ctx2);
|
sha256_hmac_final (&sha256_hmac_ctx2);
|
||||||
|
|
||||||
const u32 r0 = sha256_hmac_ctx2.opad.h[0];
|
sha256_hmac_ctx_t sha256_hmac_ctx3;
|
||||||
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];
|
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
|
#define il_pos 0
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE
|
|||||||
| OPTI_TYPE_SLOW_HASH_SIMD_LOOP;
|
| OPTI_TYPE_SLOW_HASH_SIMD_LOOP;
|
||||||
static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE;
|
static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE;
|
||||||
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
|
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
|
||||||
static const char *ST_PASS = "hashcat";
|
static const char *ST_PASS = "hashcat1";
|
||||||
static const char *ST_HASH = "$bitwarden$1*100000*bm9yZXBseUBoYXNoY2F0Lm5ldA==*zAXL7noQxkIJG82vWuqyDsnoqnKAVU7gE/8IRI6BlMs=";
|
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_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; }
|
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; }
|
||||||
|
143
tools/bitwarden2hashcat.py
Normal file
143
tools/bitwarden2hashcat.py
Normal file
@ -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"<?xml"):
|
||||||
|
try:
|
||||||
|
email, enc_key = process_xml_file(filename)
|
||||||
|
if not email or not enc_key:
|
||||||
|
sys.stderr.write("[error] %s could not be parsed properly!\n" % filename)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
data = json.loads(data)
|
||||||
|
bitw_data = BitwardenData(
|
||||||
|
email = data["userEmail"],
|
||||||
|
enc_key = data["encKey"],
|
||||||
|
key_hash = data["keyHash"],
|
||||||
|
# Usually 100000
|
||||||
|
iterations = data["kdfIterations"]
|
||||||
|
)
|
||||||
|
except (valueerror, keyerror):
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.stderr.write("Missing values, user is probably logged out.")
|
||||||
|
return
|
||||||
|
|
||||||
|
sys.stdout.write("%s: $bitwarden$2*%s*%s*%s\n" %
|
||||||
|
(os.path.basename(filename), bitw_data.iterations, base64.b64encode(bitw_data.email.encode("ascii")).decode("ascii"), bitw_data.key_hash))
|
||||||
|
|
||||||
|
# iterations = 5000 # seems to be fixed in the design
|
||||||
|
# email = bitw_data.email.lower()
|
||||||
|
# iv_mix, blob = bitw_data.enc_key.split("|")
|
||||||
|
# iv = iv_mix[2:] # skip over "0."
|
||||||
|
# iv = binascii.hexlify(base64.b64decode(iv)).decode("ascii")
|
||||||
|
# blob = binascii.hexlify(base64.b64decode(blob)).decode("ascii")
|
||||||
|
# sys.stdout.write("%s:$bitwarden$0*%s*%s*%s*%s\n" %
|
||||||
|
# (os.path.basename(filename), iterations, email, iv, blob))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("path", type=str, nargs="+")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print(args.path)
|
||||||
|
|
||||||
|
# if len(sys.argv) < 2:
|
||||||
|
# sys.stderr.write("Usage: %s <Bitwarden storage.js / com.x8bit.bitwarden_preferences.xml / Google Chrome's 'nngceckbap...' path>\n" %
|
||||||
|
# sys.argv[0])
|
||||||
|
# sys.exit(-1)
|
||||||
|
|
||||||
|
for p in args.path:
|
||||||
|
process_file(p)
|
@ -29,7 +29,7 @@ sub module_generate_hash
|
|||||||
my $kdf2 = Crypt::PBKDF2->new
|
my $kdf2 = Crypt::PBKDF2->new
|
||||||
(
|
(
|
||||||
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
||||||
iterations => 1,
|
iterations => 2,
|
||||||
output_len => 32
|
output_len => 32
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user