2021-07-14 19:31:21 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# Based on "pyvmx-cracker" (https://github.com/axcheron/pyvmx-cracker) (MIT license)
|
|
|
|
|
|
|
|
# Author: Gabriele 'matrix' Gristina
|
|
|
|
# Version: 1.0
|
|
|
|
# Date: Tue 13 Jul 2021 01:29:23 PM CEST
|
|
|
|
# License: MIT
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
from urllib.parse import unquote
|
|
|
|
from binascii import hexlify
|
|
|
|
import re
|
|
|
|
import base64
|
|
|
|
|
|
|
|
ks_re = '.+phrase/(.*?)/pass2key=(.*?):cipher=(.*?):rounds=(.*?):salt=(.*?),(.*?),(.*?)\)'
|
|
|
|
|
|
|
|
ks_struct = {
|
|
|
|
'password_hash': None,
|
|
|
|
'password_cipher': None,
|
|
|
|
'hash_round': None,
|
|
|
|
'salt': None,
|
|
|
|
'dict': None
|
|
|
|
}
|
|
|
|
|
|
|
|
def parse_keysafe(file):
|
|
|
|
try:
|
|
|
|
with open(file, 'r') as data:
|
|
|
|
lines = data.readlines()
|
|
|
|
except (OSError, IOError):
|
|
|
|
sys.exit('[-] Cannot read from file ' + data)
|
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
if 'encryption.keySafe' in line:
|
|
|
|
keysafe = line
|
|
|
|
|
|
|
|
keysafe = unquote(keysafe)
|
|
|
|
|
|
|
|
match = re.match(ks_re, keysafe)
|
|
|
|
if not match:
|
|
|
|
msg = 'Unsupported format of the encryption.keySafe line:\n' + keysafe
|
|
|
|
raise ValueError(msg)
|
|
|
|
|
|
|
|
vmx_ks = ks_struct
|
|
|
|
|
|
|
|
vmx_ks['password_hash'] = match.group(2)
|
|
|
|
if vmx_ks['password_hash'] != 'PBKDF2-HMAC-SHA-1':
|
|
|
|
msg = 'Unsupported password hash format: ' + vmx_ks['password_hash']
|
|
|
|
raise ValueError(msg)
|
|
|
|
|
|
|
|
vmx_ks['password_cipher'] = match.group(3)
|
|
|
|
if vmx_ks['password_cipher'] != 'AES-256':
|
|
|
|
msg = 'Unsupported cypher format: ' + vmx_ks['password_cypher']
|
|
|
|
raise ValueError(msg)
|
|
|
|
|
|
|
|
vmx_ks['hash_round'] = int(match.group(4))
|
|
|
|
vmx_ks['salt'] = base64.b64decode(unquote(match.group(5)))
|
2021-07-15 19:58:11 +02:00
|
|
|
vmx_ks['dict'] = base64.b64decode(match.group(7))[0:32]
|
2021-07-14 19:31:21 +02:00
|
|
|
|
|
|
|
return vmx_ks
|
|
|
|
|
|
|
|
def pyvmx(vmx):
|
|
|
|
keysafe = parse_keysafe(vmx)
|
|
|
|
print("$vmx$0$" + str(keysafe['hash_round']) + "$" + hexlify(keysafe['salt']).decode() + "$" + hexlify(keysafe['dict']).decode())
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
parser = argparse.ArgumentParser(description="vmwarevmx2hashcat extraction tool")
|
|
|
|
parser.add_argument('--vmx', required=True, help='set vmware vmx file from path', type=str)
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.vmx:
|
|
|
|
pyvmx(args.vmx)
|
|
|
|
else:
|
|
|
|
parser.print_help()
|
|
|
|
exit(1)
|