Recent TryHackMe room called “Block” inspired me to create this write-up. The task is to decrypt SMB3-encrypted communication. It turned out that sometimes we only need the captured network traffic to fulfill this task, while otherwise we need some additional info, such as user’s password or its NTLM hash. In this blog post, I would like to summarize three different approaches with practical hands-on exercises based on TryHackMe challenge. I will demonstrate methods of SMB decryption with the knowledge of the user’s password, its NTLM hash, and without any password/hash, just from the captured traffic only.

Challenge Overview

If you want to try it and follow the steps described in this post, you can download the evidence from the TryHackMe “Block” room - you need to be logged-in and then “Download Task Files”. After unzipping, you will get two files - traffic.pcapng and lsass.DMP.

Please note that lsass.DMP file can be flagged by your antimalware software as malicious, because it contains the memory dump of LSASS process (and it is often sign of the attacker presence, when someone dumped the secrets from this process).

The other file, traffic.pcapng, contains the network traffic capture of two encrypted SMB sessions. Our task is to find the usernames of persons who accessed the server, their passwords (or hashes of their passwords) and to extract the flags from the encrypted communication.

Fig. 1: Encrypted SMB traffic

Method 1: Decrypting SMB with the password

Extracting the user password

First of all, we need to extract the user password from the LSASS memory dump. Using the file command, we can see that this file contains minidump crash dump:

$ file lsass.DMP 
lsass.DMP: Mini DuMP crash report, 16 streams, Sun Oct 22 16:54:50 2023, 0x421826 type

We have several options how to extract secrets from this file. On Windows, we can use Mimikatz tool (again, it is flagged by antimalwares as hacking tool since it is often used by the attackers). The Mimikatz doesn’t work on Linux, so on Linux, we should use something more multiplatform, such as Pypykatz - Mimikatz implementation in pure Python:

$ pypykatz lsa minidump lsass.DMP
	...

	== MSV ==
		Username: mrealman
		Domain: BLOCK
		LM: NA
		NT: 1f9175a516211660c7a8143b0f36ab44
		SHA1: ccd27b4bf489ffda2251897ef86fdb488f248aef
		DPAPI: 3d618a1fffd6c879cd0b056910ec0c3100000000
	== WDIGEST [1cbb91]==
		username mrealman
		domainname BLOCK
		password None
		password (hex)

	...

	== MSV ==
		Username: eshellstrop
		Domain: BLOCK
		LM: NA
		NT: 3f29138a04aadc19214e9c04028bf381
		SHA1: 91374e6e58d7b523376e3b1eb04ae5440e678717
		DPAPI: 87c8e56bc4714d4c5659f254771559a800000000
	== WDIGEST [ca599]==
		username eshellstrop
		domainname BLOCK
		password None
		password (hex)

	...

We have obtained two user names with NTLM hashes of their passwords, but no passwords.

Now we can start with the cracking the hashes on our own machines, or, we can use online crackers, such as CrackStation. And with one of our NTLM hash, we are lucky - the password for mrealman user is Blockbuster1.

Fig. 2: Cracking the NTLM hashes with online cracker

SMB traffic decryption with the password

For analysis of the captured network traffic we can use Wireshark. When we inspect the beginning of the first SMB session, there is a Session Setup. More specific, the authentication of the user mrealman with the NTLM protocol over the network. In Wireshark, we can filter these packets using the display filter ntlmssp.

Fig. 3: NTLMSSP and SMB Session Setup

Wireshark Wiki contains interesting page about decryption of NTLM-encrypted traffic. It says that we can decrypt the traffic by providing the password in the Edit -> Preferences -> Protocols -> NTLMSSP dialog, see Figure 4.

Fig. 4: NT Password in Wireshark NTLMSSP protocol preferences

However, we also need to check the field “Try to decrypt Kerberos blobs” in the Edit -> Preferences -> Protocols -> KRB5 dialog (see Figure 6). Then, the SMB traffic should be decrypted.

Fig. 5: Decrypted SMB traffic

Method 2: Decrypting SMB with the NTLM hash

Extracting the NTLM hash

Same as before, we can use Mimikatz or Pypykatz to extract the NTLM hashes. But this time, we do not need to crack them to obtaining the user’s password.

SMB traffic decryption with the NTLM hash

The above-mentioned Wireshark Wiki also contains the information about the decryption by providing the NT hash in a keytab file. Keytab files are usually used with Kerberos and they stores long-term keys for principals.

Luckily, the Wireshark Wiki also contains reference to the CTF write-up Insomni’Hack Teaser 2023 - Autopsy, where is described how we can create keytab files with the tool ktutil. This tool is usually in the Linux packages called krb5 or krb5-util.

Alternatively, we can create keytab file with the keytab.py script mentioned in the another blog post referenced in the Wireshark Wiki. However, this script depends on Impacket, the collection of tools and libraries often used by the attackers and pentesters, thus may be flagged by your antimalware product.

Now, we can create keytab file with the NTLM hash of the second user, eshellstrop. We can also verify with the file command that our keytab file was created successfully and it contains the desired secret:

$ ktutil
ktutil:  add_entry -p eshellstrop@WORKGROUP -k 1 -key -e rc4-hmac
Key for eshellstrop@WORKGROUP (hex): 3f29138a04aadc19214e9c04028bf381
ktutil:  write_kt block.keytab
ktutil:  q
$ file block.keytab 
block.keytab: Kerberos Keytab file, realm=WORKGROUP, principal=eshellstrop/, type=91833, date=Wed Apr 29 15:00:16 2093, kvno=23

Now, we need to provide this keytab file to the Wireshark in the Edit -> Preferences -> Protocols -> KRB5 dialog. Also, check the “Try to decrypt Kerberos blobs” checkbox (see Figure 6). Then, the SMB traffic should be decrypted.

Fig. 6: Keytab with NTLM hash in Wireshark KRB5 protocol preferences

Method 3: Decrypting SMB with the captured traffic only

Disclaimer: This part is mostly inspired by the great post by Khris Tolbert, which I found almost immediately - it is the first result returned by DuckDuckGo and Google for the queries such as “decrypt SMB traffic”.

Password cracking from the captured traffic

When we have captured the beginning of the SMB session (Session Setup) and not only the later encrypted SMB traffic (e.g. transfer of large files), we could crack the user password. Sometimes it is possible, especially if the user uses not so complex password. The success of this attack depends on the password strength and on our methodology and resources (good dictionaries, rules, computing power, or sometimes, some clever ideas are also needed).

We need to extract username, domain, NTLM server challenge, NTLM client response and NT proof string (first part of NTLM client response) from the captured Session Setup. The most easy way is to use tshark, the command-line version of Wireshark:

# username domain ntproofstr ntresponse
$ tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000003' -T fields -e ntlmssp.auth.username -e ntlmssp.auth.domain -e ntlmssp.ntlmv2_response.ntproofstr -e ntlmssp.auth.ntresponse
mrealman	WORKGROUP	16e816dead16d4ca7d5d6dee4a015c14	16e816dead16d4ca7d5d6dee4a015c140101000000000000abce46bf0905da01da0395279d6ab0260000000002000a0042004c004f0043004b0001001e00570049004e002d00320032003500380048004800430042004e00510052000400120062006c006f0063006b002e00740068006d0003003200570049004e002d00320032003500380048004800430042004e00510052002e0062006c006f0063006b002e00740068006d000500120062006c006f0063006b002e00740068006d0007000800abce46bf0905da01060004000200000008003000300000000000000000000000000000002a514197857a27e5d174fa71e991a6853a1360abfc915b014a33b215c721873f0a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0030002e0032002e003700300000000000
eshellstrop	WORKGROUP	0ca6227a4f00b9654a48908c4801a0ac	0ca6227a4f00b9654a48908c4801a0ac0101000000000000d7e342c60905da01f68ee398f7ead88e0000000002000a0042004c004f0043004b0001001e00570049004e002d00320032003500380048004800430042004e00510052000400120062006c006f0063006b002e00740068006d0003003200570049004e002d00320032003500380048004800430042004e00510052002e0062006c006f0063006b002e00740068006d000500120062006c006f0063006b002e00740068006d0007000800d7e342c60905da01060004000200000008003000300000000000000000000000000000003435b9adfc23d7af91c4da961f2c011bb0f077d997cb2a9cfbc93355f49ac1960a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0030002e0032002e003700300000000000

# ntlmserverchallenge
$ tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000002' -T fields -e ntlmssp.ntlmserverchallenge
2a9c5234abca01e7
64fe52d6bf528fba

Now we prepare the text file for the password-cracking tool hashcat. The format is:

username::domain:ntlmserverchallenge:ntproofstr:rest_of_ntresponse

Let say that our text file is called ntlm.txt. Then, we can try the dictionary attack with the well-known wordlist called rockyou.txt. We will use the hashcat straight attack mode (-a 0), NetNTLMv2 hash mode (-m 5600) and optimized kernels enabled (-O, this limits password length):

$ hashcat -O -a 0 -m 5600 ntlm.txt rockyou.txt 

...

MREALMAN::WORKGROUP:2a9c5234abca01e7:16e816dead16d4ca7d5d6dee4a015c14:0101000000000000abce46bf0905da01da0395279d6ab0260000000002000a0042004c004f0043004b0001001e00570049004e002d00320032003500380048004800430042004e00510052000400120062006c006f0063006b002e00740068006d0003003200570049004e002d00320032003500380048004800430042004e00510052002e0062006c006f0063006b002e00740068006d000500120062006c006f0063006b002e00740068006d0007000800abce46bf0905da01060004000200000008003000300000000000000000000000000000002a514197857a27e5d174fa71e991a6853a1360abfc915b014a33b215c721873f0a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0030002e0032002e003700300000000000:Blockbuster1

...
Approaching final keyspace - workload adjusted.  

                                                 
Session..........: hashcat
Status...........: Exhausted
Hash.Type........: NetNTLMv2
Hash.Target......: ntlm.txt
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Recovered........: 1/2 (50.00%) Digests, 1/2 (50.00%) Salts
Progress.........: 28688770/28688770 (100.00%)

As the abbreviated output above stated, one password for mrealman was cracked, while the second password is still unknown.

Now we can decrypt the SMB traffic using the Method 1, or we can compute the SMB session keys from the cracked password and the values captured during SMB Session Setup.

Compute SMB session key

The SMB traffic is encrypted with session key, which we can now compute. We will need the username, domain, NTLM hash of the password (or the password itself), NT proof string, NTLM server challenge and encrypted session key and SMB session ID from the SMB Session Setup (or NTLMSSP part of the authentification). Most of the values we already know. For the completeness, we can extract them with the following tshark commands:

# username domain ntproofstr sessionkey sessionid
$ tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000003' -T fields -e ntlmssp.auth.username -e ntlmssp.auth.domain -e ntlmssp.ntlmv2_response.ntproofstr -e ntlmssp.auth.sesskey -e smb2.sesid
mrealman	WORKGROUP	16e816dead16d4ca7d5d6dee4a015c14	fde53b54cb676b9bbf0fb1fbef384698	0x0000100000000041
eshellstrop	WORKGROUP	0ca6227a4f00b9654a48908c4801a0ac	c24f5102a22d286336aac2dfa4dc2e04	0x0000100000000045

# ntlmserverchallenge
$ tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000002' -T fields -e ntlmssp.ntlmserverchallenge
2a9c5234abca01e7
64fe52d6bf528fba

Next, if we have password instead of user’s NTLM hash, we need to compute its NTLM hash as MD4 of password encoded as UTF16-LE.

Then, we can compute another values, which we need to obtain the session key: * response key as HMAC-MD5 from the user and domain, with the NTLM hash of password as the HMAC key, * key exchange key as HMAC-MD5 from the NT proof string, with response key as the HMAC key,

Now, we can decrypt the session key from the encrypted session key obtained with tshark before (ntlmssp.auth.sesskey). The desired session key is encrypted with RC4 cipher, with key exchange key as the RC4 key.

The following simple code in Python3 will do the job for us:

from Crypto.Cipher import ARC4
from Crypto.Hash import MD4, MD5, HMAC

password = 'Blockbuster1'
passwordHash = MD4.new(password.encode('utf-16-le')).hexdigest()
username = 'mrealman'
domain = 'workgroup'
ntProofStr = '16e816dead16d4ca7d5d6dee4a015c14'
serverChallenge = '2a9c5234abca01e7'
sessionKey = 'fde53b54cb676b9bbf0fb1fbef384698'

responseKey = HMAC.new(bytes.fromhex(passwordHash), (username.upper()+domain.upper()).encode('utf-16-le'), MD5).digest()
keyExchangeKey = HMAC.new(responseKey, bytes.fromhex(ntProofStr), MD5).digest()
decryptedSessionKey = ARC4.new(keyExchangeKey).decrypt(bytes.fromhex(sessionKey))
print('Decrypted SMB Session Key is: {}'.format(decryptedSessionKey.hex()))

In our case, the session IDs and the session keys are the following:

session id session key
4100000000100000 7e8b77fee909abb7856af24e4bfd9608
4500000000100000 facfbdf010d00aa2574c7c41201099e8

Please note that the session IDs are formatted as hex streams instead of the hexadecimal numbers returned by tshark- thus the bytes need to be reversed - this is the format expected by Wireshark (see Figure 7).

SMB traffic decryption with the session keys

When we have the decrypted session keys, we can provide them to the Wireshark. Fill the Session ID and Session Key in the “Secret session keys for decryption” list in the Edit -> Preferences -> Protocols -> SMB2 dialog, see Figure 7. Then, the SMB traffic should be decrypted.

Fig. 7: Secret session keys for decryption in Wireshark SMB2 protocol preferences

Extract the files from the SMB communication

After the successful decryption of the SMB communication, we should be able to see the SMB traffic and transfering the two CSV files. The flags for the CTF challenge are hidden in these CSV files. And we can extract these files via the File -> Export Objects -> SMB dialog in Wireshark, see Figure 8.

Fig. 8: Extcract the transfered files - Export SMB Objects in Wireshark

Conclusion

We have tried several different approaches and methods for decrypting the encrypted SMB traffic. Depending on the circumstances, we need just the captured traffic and we will be able to crack the user password and decrypt the communication. If the password cracking is not successful, then we also need some additional info such as the user’s password or at least its NTLM hash, which can be obtained for example from the memory dump of the LSASS process.

The TryHackme room “Block” provides a good digital evidence for the practical demonstration and hands-on labs related to the topics covered in this blog post.

Used Tools

References