October 28, 2026
THM - Block
Encryption? What encryption?

By SleepySOC
4 min read
- 1 Q1 : What is the username of the first person who accessed our server?
- 2 Q2 : What is the password of the user in question 1?
- 3 Q3 : What is the flag that the first user got access to?
- 4 Q4 : What is the username of the second person who accessed our server?
- 5 Q5 : What is the hash of the user in question 4?
One of your junior system administrators forgot to deactivate two accounts from a pair of recently fired employees. We believe these employees used the credentials they were given in order to access some of the many private files from our server, but we need concrete proof. The junior system administrator only has a small network capture of the incident and a memory dump of the Local Security Authority Subsystem Service process. Fortunately, for your company, that is all you need.
Click on the Download Task Files button at the top of this task. You will be provided with an evidence.zip file.
Extract the zip file's contents and recover the information in order to answer the questions.
Note: For free users using the AttackBox, the challenge is best done using your own environment. Some browsers may detect the file as malicious. The zip file is safe to download with md5 of 286c133a1b67c068f86cef06785e104d. In general, as a security practice, download the zip and analyze the forensic files on a dedicated lab machine, and not on your host OS.
Lets Start rolling…
Q1 : What is the username of the first person who accessed our server?
Easy just open the given pcap file in wireshark and use the filter :
smb2smb2and you will see
ANSWER : mrealman
Q2 : What is the password of the user in question 1?
For this one we need to use some of our Hacking skills
lets understand first what we are going to do when we need to extract a password hash of a user we do it with tools like mimikatz and run it on process called lsass.exe but its on the live memory not on a dump. As you can see inside the given zip file we have a lsass.DMP file which means its not a full image of the memory but an image of on single process lsass ( also known as mini dump ) so the problem is solved because now we have a mini dump of lsass process. But here we will use pypykatz same as mimikatz but python based so lets start.
as you can see we have the hashes of the password lets reverse it
ANSWER : Blockbuster1
Q3 : What is the flag that the first user got access to?
Its kinda tricky but i will try my best to keep it simple first you have to take this script and paste is it inside a file named like session.py and run it The script :
import hashlib
import hmac
import argparse
from Cryptodome.Cipher import ARC4
from Cryptodome.Hash import MD4
def generate_encrypted_session_key(key_exchange_key, exported_session_key):
cipher = ARC4.new(key_exchange_key)
return cipher.encrypt(exported_session_key)
def hex_to_bytes(hex_str):
return bytes.fromhex(hex_str)
def bytes_to_hex(byte_str):
return byte_str.hex()
def main():
parser = argparse.ArgumentParser(description=”Calculate the Random Session Key based on data from a PCAP (maybe).”)
parser.add_argument(“-u”, “ — user”, required=True, help=”User name”)
parser.add_argument(“-d”, “ — domain”, required=True, help=”Domain name”)
parser.add_argument(“-p”, “ — password”, required=True, help=”Password of User”)
parser.add_argument(“-n”, “ — ntproofstr”, required=True, help=”NTProofStr. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-k”, “ — key”, required=True, help=”Encrypted Session Key. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-v”, “ — verbose”, action=”store_true”, help=”increase output verbosity”)
args = parser.parse_args()
user = str(args.user).upper().encode(‘utf-16le’)
domain = str(args.domain).upper().encode(‘utf-16le’)
passw = args.password.encode(‘utf-16le’)
hash1 = hashlib.new(‘md4’, passw)
password = hash1.digest()
h = hmac.new(password, digestmod=hashlib.md5)
h.update(user + domain)
resp_nt_key = h.digest()
nt_proof_str = hex_to_bytes(args.ntproofstr)
h = hmac.new(resp_nt_key, digestmod=hashlib.md5)
h.update(nt_proof_str)
key_exch_key = h.digest()
encrypted_session_key = hex_to_bytes(args.key)
rsess_key = generate_encrypted_session_key(key_exch_key, encrypted_session_key)
if args.verbose:
print(f”USER WORK: {user.decode(‘utf-16le’)} {domain.decode(‘utf-16le’)}”)
print(f”PASS HASH: {bytes_to_hex(password)}”)
print(f”RESP NT: {bytes_to_hex(resp_nt_key)}”)
print(f”NT PROOF: {bytes_to_hex(nt_proof_str)}”)
print(f”KeyExKey: {bytes_to_hex(key_exch_key)}”)
print(f”Random SK: {bytes_to_hex(rsess_key)}”)
if __name__ == “__main__”:
main()
import hashlib
import hmac
import argparse
from Cryptodome.Cipher import ARC4
from Cryptodome.Hash import MD4
def generate_encrypted_session_key(key_exchange_key, exported_session_key):
cipher = ARC4.new(key_exchange_key)
return cipher.encrypt(exported_session_key)
def hex_to_bytes(hex_str):
return bytes.fromhex(hex_str)
def bytes_to_hex(byte_str):
return byte_str.hex()
def main():
parser = argparse.ArgumentParser(description=”Calculate the Random Session Key based on data from a PCAP (maybe).”)
parser.add_argument(“-u”, “ — user”, required=True, help=”User name”)
parser.add_argument(“-d”, “ — domain”, required=True, help=”Domain name”)
parser.add_argument(“-p”, “ — password”, required=True, help=”Password of User”)
parser.add_argument(“-n”, “ — ntproofstr”, required=True, help=”NTProofStr. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-k”, “ — key”, required=True, help=”Encrypted Session Key. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-v”, “ — verbose”, action=”store_true”, help=”increase output verbosity”)
args = parser.parse_args()
user = str(args.user).upper().encode(‘utf-16le’)
domain = str(args.domain).upper().encode(‘utf-16le’)
passw = args.password.encode(‘utf-16le’)
hash1 = hashlib.new(‘md4’, passw)
password = hash1.digest()
h = hmac.new(password, digestmod=hashlib.md5)
h.update(user + domain)
resp_nt_key = h.digest()
nt_proof_str = hex_to_bytes(args.ntproofstr)
h = hmac.new(resp_nt_key, digestmod=hashlib.md5)
h.update(nt_proof_str)
key_exch_key = h.digest()
encrypted_session_key = hex_to_bytes(args.key)
rsess_key = generate_encrypted_session_key(key_exch_key, encrypted_session_key)
if args.verbose:
print(f”USER WORK: {user.decode(‘utf-16le’)} {domain.decode(‘utf-16le’)}”)
print(f”PASS HASH: {bytes_to_hex(password)}”)
print(f”RESP NT: {bytes_to_hex(resp_nt_key)}”)
print(f”NT PROOF: {bytes_to_hex(nt_proof_str)}”)
print(f”KeyExKey: {bytes_to_hex(key_exch_key)}”)
print(f”Random SK: {bytes_to_hex(rsess_key)}”)
if __name__ == “__main__”:
main()
run it and you will see a key paste that key inside of wireshark Go to Wireshark →Edit → preferences → Protocols → smb2 → edit paste it here to decrypt. after we decrypt smb2 go to the file → Export Objects → SMB… and you will see this file save the file.
ANSWER : THM{SmB_DeCrypTing_who_Could_Have_Th0ughT}
Q4 : What is the username of the second person who accessed our server?
Same as Q1
ANSWER : eshellstrop
Q5 : What is the hash of the user in question 4?
Same as Q2 but the difference is we dont need to reverse the hash just paste the RAW hash in the answer filed
ANSWER : 3f29138a04aadc19214e9c04028bf381
Q6 : What is the flag that the second user got access to?
Same as Q3 but the script is a bit different
import hashlib
import hmac
import argparse
from Cryptodome.Cipher import ARC4
from Cryptodome.Cipher import DES
from Cryptodome.Hash import MD4
def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey):
cipher = ARC4.new(keyExchangeKey)
cipher_encrypt = cipher.encrypt
sessionKey = cipher_encrypt(exportedSessionKey)
return sessionKey
parser = argparse.ArgumentParser(description=”Calculate the Random Session Key based on data from a PCAP (maybe).”)
parser.add_argument(“-u”,” — user”,required=True,help=”User name”)
parser.add_argument(“-d”,” — domain”,required=True, help=”Domain name”)
parser.add_argument(“-hsh”,” — hash”,required=True,help=”User’s NTLM Hash”)
parser.add_argument(“-n”,” — ntproofstr”,required=True,help=”NTProofStr. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-k”,” — key”,required=True,help=”Encrypted Session Key. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-v”, “ — verbose”, action=”store_true”, help=”increase output verbosity”)
args = parser.parse_args()
user = str(args.user).upper().encode(‘utf-16le’)
domain = str(args.domain).upper().encode(‘utf-16le’)
password = bytes.fromhex(args.hash)
h = hmac.new(password, digestmod=hashlib.md5)
h.update(user+domain)
respNTKey = h.digest()
NTproofStr = bytes.fromhex(args.ntproofstr)
h = hmac.new(respNTKey, digestmod=hashlib.md5)
h.update(NTproofStr)
KeyExchKey = h.digest()
RsessKey = generateEncryptedSessionKey(KeyExchKey, bytes.fromhex(args.key))
if args.verbose:
print(“USER WORK: “ + user.decode(‘utf-16le’) + “” + domain.decode(‘utf-16le’))
print(“PASS HASH: “ + password.hex())
print(“RESP NT: “ + respNTKey.hex())
print(“NT PROOF: “ + NTproofStr.hex())
print(“KeyExKey: “ + KeyExchKey.hex())
print(“Random SK: “ + RsessKey.hex())
import hashlib
import hmac
import argparse
from Cryptodome.Cipher import ARC4
from Cryptodome.Cipher import DES
from Cryptodome.Hash import MD4
def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey):
cipher = ARC4.new(keyExchangeKey)
cipher_encrypt = cipher.encrypt
sessionKey = cipher_encrypt(exportedSessionKey)
return sessionKey
parser = argparse.ArgumentParser(description=”Calculate the Random Session Key based on data from a PCAP (maybe).”)
parser.add_argument(“-u”,” — user”,required=True,help=”User name”)
parser.add_argument(“-d”,” — domain”,required=True, help=”Domain name”)
parser.add_argument(“-hsh”,” — hash”,required=True,help=”User’s NTLM Hash”)
parser.add_argument(“-n”,” — ntproofstr”,required=True,help=”NTProofStr. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-k”,” — key”,required=True,help=”Encrypted Session Key. This can be found in PCAP (provide Hex Stream)”)
parser.add_argument(“-v”, “ — verbose”, action=”store_true”, help=”increase output verbosity”)
args = parser.parse_args()
user = str(args.user).upper().encode(‘utf-16le’)
domain = str(args.domain).upper().encode(‘utf-16le’)
password = bytes.fromhex(args.hash)
h = hmac.new(password, digestmod=hashlib.md5)
h.update(user+domain)
respNTKey = h.digest()
NTproofStr = bytes.fromhex(args.ntproofstr)
h = hmac.new(respNTKey, digestmod=hashlib.md5)
h.update(NTproofStr)
KeyExchKey = h.digest()
RsessKey = generateEncryptedSessionKey(KeyExchKey, bytes.fromhex(args.key))
if args.verbose:
print(“USER WORK: “ + user.decode(‘utf-16le’) + “” + domain.decode(‘utf-16le’))
print(“PASS HASH: “ + password.hex())
print(“RESP NT: “ + respNTKey.hex())
print(“NT PROOF: “ + NTproofStr.hex())
print(“KeyExKey: “ + KeyExchKey.hex())
print(“Random SK: “ + RsessKey.hex())
same .py file and run it. After we get a random key go to wireshark to decrypt smb2 like before.
ANSWER : THM{No_PasSw0Rd?_No_Pr0bl3m}
Finished hope you enjoyed !!! see you soon….