Skip to content

Instantly share code, notes, and snippets.

@dbeinder
Last active April 3, 2020 23:32
Show Gist options
  • Save dbeinder/74518726ae64ef0b964947e82fbbcf0f to your computer and use it in GitHub Desktop.
Save dbeinder/74518726ae64ef0b964947e82fbbcf0f to your computer and use it in GitHub Desktop.
openssl enc hashcat poc
# install requirements: pip3 install pycryptodome hashlib
import sys, os
from binascii import unhexlify, hexlify
from hashlib import md5, sha256
from Crypto.Cipher import AES
# default setting, "openssl enc" pre v1.1.0
def kdf_aes256_md5(pwd, salt):
h1 = md5(pwd + salt).digest()
h2 = md5(h1 + pwd + salt).digest()
iv = md5(h2 + pwd + salt).digest()
print("h1 = " + hexlify(h1).decode('ascii'))
print("h2 = " + hexlify(h2).decode('ascii'))
aes_key = h1 + h2
return aes_key, iv
#default setting "openssl enc" since v1.1.0
def kdf_aes256_sha256(pwd, salt):
h1 = sha256(pwd + salt).digest()
h2 = sha256(h1 + pwd + salt).digest()
print("h2 = " + hexlify(h2).decode('ascii'))
aes_key = h1
iv = h2[:16] # first 16 bytes
return aes_key, iv
# usage: openssl_poc.py encrypted_file.aes "password_to_try" "known_header"
# all vars are raw bytes, there are no coversions to hex strings
password_to_try = sys.argv[2].encode()
known_header = sys.argv[3].encode()
with open(sys.argv[1], "rb") as f:
if f.read(8) != b"Salted__":
print("File " + sys.argv[1] + " is not a 'openssl enc' salted file, maybe it is base64 coded?")
sys.exit(-1)
file_salt = f.read(8)
first_block = f.read(16)
print("File: " + sys.argv[1])
print("salt = " + hexlify(file_salt).decode('ascii'))
print("checking password [" + sys.argv[2] + "] = " + hexlify(password_to_try).decode('ascii'))
kdfs = { "OpenSSL 1.0.X default: MD5 / AES256": kdf_aes256_md5,
"OpenSSL 1.1.X default: SHA256 / AES256": kdf_aes256_sha256 }
for desc, kdf in kdfs.items():
print("\n == " + desc + " ==")
aes_key, iv = kdf(password_to_try, file_salt)
print("aes_key = " + hexlify(aes_key).decode('ascii').upper())
print("iv = " + hexlify(iv).decode('ascii').upper())
aes = AES.new(aes_key, AES.MODE_CBC, iv)
first_block_plain = aes.decrypt(first_block)
pwd_is_good = first_block_plain[:len(known_header)] == known_header
print("password [" + sys.argv[2] + "] correct: " + str(pwd_is_good))
print("last block decrypted: [" + str(first_block_plain) + "]")
#!/usr/bin/env python3
import sys, os
from binascii import unhexlify, hexlify
if len(sys.argv) != 3:
print("usage: openssl_tohash.py encrypted_file.aes known_header")
print(" Format: $opensslenc$salt*first_block*known_header")
sys.exit(-1)
try:
file_size = os.stat(sys.argv[1]).st_size
if file_size < 32:
print("File " + sys.argv[1] + " is not a 'openssl enc' salted file, can't be smaller than 32 bytes")
sys.exit(-1)
single_block = file_size == 32
with open(sys.argv[1], "rb") as f:
if f.read(8) != b"Salted__":
print("File " + sys.argv[1] + " is not a 'openssl enc' salted file, maybe it is base64 coded?")
sys.exit(-1)
file_salt = f.read(8)
first_block = f.read(16)
except EnvironmentError as err:
print("Error reading file: " + str(err))
sys.exit(-1)
outstr = "$opensslenc$" + hexlify(file_salt).decode('ascii')
outstr += "*" + hexlify(first_block).decode('ascii')
outstr += "*" + hexlify(sys.argv[2].encode()).decode('ascii')
print(outstr)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment