-
Notifications
You must be signed in to change notification settings - Fork 5
/
machash.py
executable file
·55 lines (48 loc) · 1.76 KB
/
machash.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3
# This software is Copyright (c) 2017 Jake Magers <jmagers12 at gmail.com>,
# and it is hereby released to the general public under the following terms:
# Redistribution and use in source and binary forms, with or without
# modification, are permitted.
import argparse
import plistlib
import sys
HASH_TYPE = 'SALTED-SHA512-PBKDF2'
# Arguments
parser = argparse.ArgumentParser(description='Convert Mac plist password file '
'to hash file')
parser.add_argument('plistfile',
type=argparse.FileType('rb'),
help='plist file to convert to hash')
parser.add_argument('hashfile',
type=argparse.FileType('w'),
nargs='?',
default='-',
help='file to store resulting hash')
args = parser.parse_args()
# Load plist file
try:
plist = plistlib.load(args.plistfile)
except plistlib.InvalidFileException:
sys.exit("Could not parse plist file!")
# Collect hash data
try:
username = plist['name'][0] + ':'
except (KeyError, IndexError):
username = ''
try:
shadow_hash_data = plistlib.loads(plist['ShadowHashData'][0])
except (KeyError, IndexError):
sys.exit("ShadowHashData not found in plist file!")
except plistlib.InvalidFileException:
sys.exit("Could not load ShadowHashData from plist file!")
try:
data = shadow_hash_data[HASH_TYPE]
except KeyError:
sys.exit("ShadowHashData is not of type '%s' and therefore incompatible!"
% HASH_TYPE)
iterations = str(data['iterations'])
salt = data['salt'].hex()
entropy = data['entropy'].hex()[:128]
# Format and output hash data
formatted_hash = '$'.join([username, 'ml', iterations, salt, entropy])
print(formatted_hash, file=args.hashfile)