Forked from khr0x40sh/random_session_key_calc.py
Last active
August 19, 2024 21:14
-
-
Save cicero343/b8eac1a5e5ac46d15ac8dee805388fc4 to your computer and use it in GitHub Desktop.
Get Session Key for encrypted traffic in PCAP (Interactive)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
This is a Python3 improved/interactive version of the script made by khr0x40sh for decrypting encrypted session keys in a PCAP file to view encrypted traffic. | |
If you don't specify the parameters, it should ask you for the parameter values. | |
It will check to see if pycryptodomex is installed, and if not, it will install it. | |
It can also accept NTML hashes directly as well as passwords. | |
Usage: | |
python3 script_name.py -u USER -d DOMAIN -p PASSWORD -n NT_PROOF_STR -k ENCRYPTED_SESSION_KEY | |
Example: | |
python3 script_name.py -u alice -d EXAMPLE -p secret123 -n aabbccddeeff00112233445566778899 -k aabbccddeeff00112233445566778899 | |
Description: | |
This script calculates the Random Session Key based on data extracted from a PCAP file (possibly). | |
It uses the NTLM hash of the user's password, NTProofStr, and an encrypted session key to generate a session key via RC4 encryption. | |
""" | |
import sys | |
import subprocess | |
import hashlib | |
import hmac | |
import argparse | |
import binascii | |
# Add user's local site-packages to sys.path | |
import site | |
site.addsitedir(site.getusersitepackages()) | |
# Function to install pycryptodomex | |
def install_pycryptodomex(): | |
try: | |
# Check if pip is installed | |
subprocess.check_call([sys.executable, "-m", "pip", "--version"]) | |
except subprocess.CalledProcessError: | |
print("Error: pip is not installed. Please install pip first.") | |
sys.exit(1) | |
# Attempt to install pycryptodomex | |
try: | |
subprocess.check_call([sys.executable, "-m", "pip", "install", "--user", "pycryptodomex"]) | |
except subprocess.CalledProcessError: | |
print("Failed to install pycryptodomex. Please install it manually using 'pip install pycryptodomex'.") | |
sys.exit(1) | |
# Attempt to import Cryptodome, install if missing | |
try: | |
from Cryptodome.Cipher import ARC4 | |
from Cryptodome.Hash import MD4 | |
except ImportError: | |
print("pycryptodomex is not installed. Attempting to install it now...") | |
install_pycryptodomex() | |
# Try importing again after installation | |
try: | |
from Cryptodome.Cipher import ARC4 | |
from Cryptodome.Hash import MD4 | |
except ImportError: | |
print("Failed to import pycryptodomex after installation. Please install it manually.") | |
sys.exit(1) | |
def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey): | |
cipher = ARC4.new(keyExchangeKey) | |
cipher_encrypt = cipher.encrypt | |
sessionKey = cipher_encrypt(exportedSessionKey) | |
return sessionKey | |
def md4_hash(data): | |
"""Calculate MD4 hash using pycryptodomex.""" | |
hash_obj = MD4.new() | |
hash_obj.update(data) | |
return hash_obj.digest() | |
# Argument parser | |
parser = argparse.ArgumentParser(description="Calculate the Random Session Key based on data from a PCAP (maybe).") | |
parser.add_argument("-u", "--user", help="User name (prompted if not provided)") | |
parser.add_argument("-d", "--domain", help="Domain name (prompted if not provided)") | |
parser.add_argument("-p", "--password", help="Password of User or NTLM hash (prompted if not provided)") | |
parser.add_argument("-n", "--ntproofstr", help="NTProofStr (Hex Stream) (prompted if not provided)") | |
parser.add_argument("-k", "--key", help="Encrypted Session Key (Hex Stream) (prompted if not provided)") | |
parser.add_argument("-v", "--verbose", action="store_true", help="Increase output verbosity") | |
args = parser.parse_args() | |
# Prompt interactively if arguments are missing | |
if not args.user: | |
args.user = input("What is the username of the user? ").strip() | |
if not args.domain: | |
args.domain = input("What is the workgroup (domain)? ").strip() | |
if not args.password: | |
args.password = input("What is the password of the user or NTLM hash? ").strip() | |
if not args.ntproofstr: | |
args.ntproofstr = input("What is the NTProofStr (Hex Stream)? ").strip() | |
if not args.key: | |
args.key = input("What is the Encrypted Session Key (Hex Stream)? ").strip() | |
# Determine if password is provided as NTLM hash or plaintext password | |
if len(args.password) == 32 and all(c in '0123456789abcdefABCDEF' for c in args.password): | |
# Use provided NTLM hash | |
password = binascii.unhexlify(args.password) | |
else: | |
# Treat as plaintext password | |
passw = args.password.encode('utf-16le') | |
password = md4_hash(passw) | |
# Convert NTProofStr and Key from hex to binary data | |
try: | |
NTproofStr = binascii.unhexlify(args.ntproofstr) | |
key = binascii.unhexlify(args.key) | |
except binascii.Error: | |
print("Error: NTProofStr or Encrypted Session Key is not a valid hex string.") | |
sys.exit(1) | |
# Calculate the ResponseNTKey | |
h = hmac.new(password, digestmod=hashlib.md5) | |
h.update(args.user.upper().encode('utf-16le') + args.domain.upper().encode('utf-16le')) | |
respNTKey = h.digest() | |
# Use NTProofStr and ResponseNTKey to calculate Key Exchange Key | |
h = hmac.new(respNTKey, digestmod=hashlib.md5) | |
h.update(NTproofStr) | |
KeyExchKey = h.digest() | |
# Calculate the Random Session Key by decrypting Encrypted Session Key with Key Exchange Key via RC4 | |
RsessKey = generateEncryptedSessionKey(KeyExchKey, key) | |
# Print results | |
if args.verbose: | |
print("USER WORK: ", args.user.upper() + args.domain.upper()) | |
print("PASS HASH: ", binascii.hexlify(password).decode()) | |
print("RESP NT: ", binascii.hexlify(respNTKey).decode()) | |
print("NT PROOF: ", binascii.hexlify(NTproofStr).decode()) | |
print("KeyExKey: ", binascii.hexlify(KeyExchKey).decode()) | |
print("Random SK: ", binascii.hexlify(RsessKey).decode()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks to @khr0x40sh