# Block

{% embed url="<https://tryhackme.com/r/room/blockroom>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

The Challenge provides us with a PCAP file and a dump of LSASS. We start by analyzing the PCAP file and finding encrypted SMB traffic. The description of the room indicates that it needs to be decrypted. The questions of the challenge ask us to find the username, password, or password hash and the flag (possibly the content of the transferred files) of the respective users. This should all be possible via the PCAP file and the LSASS dump.

## Investigation On First User

### Getting Usernames

We find the first username in the 11th packet, the Session Setup Request. We could have also queried for the `ntlmssp` packet, which reveals us both Session Setup Request happening.

<figure><img src="/files/8PezpXGUPCRIvqfX77il" alt=""><figcaption></figcaption></figure>

The filter `ntlmssp` in Wireshark is used to display only packets that contain NTLM (NT LAN Manager) Security Support Provider (SSP) protocol data. NTLMSSP is a security protocol used in various Microsoft network authentication protocols, particularly in environments where Kerberos cannot be used. We are able to identify the users `mrealman` and `eshellstrop`.

<figure><img src="/files/k1KY7Pt1B8rsotcr8DfL" alt=""><figcaption></figcaption></figure>

### Retrieving The Password

For the password, the LSASS dump was first examined using pypykatz. Unfortunately, this did not give a positive result for the first user - more on that later. Neither hash nor plain text passwords were available for the first user in the dump. We will therefore probably obtain these from the PCAP. We have the option of doing this manually and by taking a closer look at the session setup requests. Or using a tool to extract the hashes.

#### Manual approach:

**Extract the following:**

* **Username**: The user's account name. **\[found in 11th packet]**
* **Domain**: The domain or workgroup name (often referred to as the target name). **\[found in 11th packet]**
* **Server Challenge**: The 8-byte challenge sent by the server. **\[found in 10th packet]**
* **NT Proof String (NTLMv2 Response)**: The first 16 bytes of the NTLMv2 response, which is the HMAC-MD5 hash. **\[found in 11th packet]**
* **Challenge Blob**: The remaining part of the NTLMv2 response, including the timestamp, client challenge, target information, etc. **\[found in 11th packet - NTLM Response]**

Then concatenate the the necessary items to a NTLMv2 structure:

```
<username>::<domain>:<server_challenge>:<nt_proof_string>:<blob>
```

#### Tool

The PCredz tool allows us to extract the hashes from the PCAP file.

{% embed url="<https://github.com/lgandx/PCredz>" %}

We just need to provide the PCAP file and be able to retrieve the NTLMv2 hashes of `mrealman` and `eshellstrop`.

<figure><img src="/files/sjMgg7qB5zhb21tfRdRl" alt=""><figcaption></figcaption></figure>

With Hashcat we are able to retrieve the password of `mrealman`. Unfortunately, the hash of `eshellstrop` is not crackable with the `rockyou.txt` wordlist.

<figure><img src="/files/unnTqjkftAVzArSYKIdr" alt=""><figcaption></figcaption></figure>

### Retrieving The Flag

We now have to decrypt the encrypted SMB traffic to get to the transferred artifacts and extract and view them. Here I came across the following source: a very good writeup on decrypting SMB traffic using only the information we have available in a PCAP.

{% embed url="<https://medium.com/maverislabs/decrypting-smb3-traffic-with-just-a-pcap-absolutely-maybe-712ed23ff6a2>" %}

The encrypted session key found in the packet can be decrypted by using the key exchange key, which can be derived from the contents of the PCAP file.

The following list of items is necessary to generate the session key (and shows the general approach), which can then be inserted into Wireshark with the matching session ID to decrypt the traffic. We have to do this for each user. The writeup also provides us with a Python script to calculate it. We already have the username, password and domain. We still need the `NTProofStr` and the response key

{% code overflow="wrap" %}

```
-Unicode (utf-16le) of password-MD4 hash of the above (This is also the NTLM Hash of the password)
-Unicode(utf-16le) and Uppercase of Username and Domain/Workgroup together 
-Calculating the ResponseKeyNT via HMAC_MD5(NTLM Hash, Unicode of User/Domain above)
-NTProofStr (can be calculated but not needed as it is present in the PCAP)
-Calculating the KeyExchangeKey via HMAC_MD5(ResponseKeyNT,NTProofStr)
-Decrypt the Encrypted Session Key via RC4 and the Key Exchange Key to finally get the Random Session Key
```

{% endcode %}

The `NTProofString` can also be found in the `ntmlssp` packet...

<figure><img src="/files/4KJXOcO6bpAXpksHwtBr" alt=""><figcaption></figcaption></figure>

... as well as the encrypted session key.

<figure><img src="/files/yDr22m1M7tVJpdXv2wSi" alt=""><figcaption></figcaption></figure>

We use the Python script from `Maveris Labs` for this, but adapt it so that it runs for Python3 and extend it so that not only passwords but also the hashes can be used directly. This is relevant for the second user, as we were unable to crack the hash for this user.

{% embed url="<https://medium.com/maverislabs/decrypting-smb3-traffic-with-just-a-pcap-absolutely-maybe-712ed23ff6a2>" %}

The following shows the modified script:

{% code title="calc\_smb\_session\_key.py" lineNumbers="true" %}

```python
import hashlib
import hmac
import argparse
import binascii

# stolen from impacket. Thank you all for your wonderful contributions to the community
try:
    from Cryptodome.Cipher import ARC4
    from Cryptodome.Cipher import DES
    from Cryptodome.Hash import MD4
except Exception as e:
    print("Warning: You don't have any crypto installed. You need pycryptodomex")
    print("See https://pypi.org/project/pycryptodomex/")
    raise e

def generate_encrypted_session_key(key_exchange_key, exported_session_key):
    cipher = ARC4.new(key_exchange_key)
    cipher_encrypt = cipher.encrypt
    session_key = cipher_encrypt(exported_session_key)
    return session_key

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", help="Password of User")
parser.add_argument("-ph", "--passwordhash", help="NTLM Hash of the Password (in Hex)")
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()

# Validate that either password or password hash is provided
if not args.password and not args.passwordhash:
    parser.error("You must provide either --password or --passwordhash")

# Upper Case User and Domain
user = str(args.user).upper().encode('utf-16le')
domain = str(args.domain).upper().encode('utf-16le')

# If password is provided, calculate the NTLM hash
if args.password:
    passw = args.password.encode('utf-16le')
    hash1 = hashlib.new('md4', passw)
    password_hash = hash1.digest()
else:
    # Use provided password hash (in hex) instead of calculating it
    password_hash = binascii.unhexlify(args.passwordhash)

# Calculate the ResponseNTKey
h = hmac.new(password_hash, digestmod=hashlib.md5)
h.update(user + domain)
resp_nt_key = h.digest()

# Use NTProofSTR and ResponseNTKey to calculate Key Exchange Key
nt_proof_str = binascii.unhexlify(args.ntproofstr)
h = hmac.new(resp_nt_key, digestmod=hashlib.md5)
h.update(nt_proof_str)
key_exch_key = h.digest()

# Calculate the Random Session Key by decrypting Encrypted Session Key with Key Exchange Key via RC4
r_sess_key = generate_encrypted_session_key(key_exch_key, binascii.unhexlify(args.key))

if args.verbose:
    print("USER WORK: " + user.decode('utf-16le') + domain.decode('utf-16le'))
    if args.password:
        print("PASS HASH: " + binascii.hexlify(password_hash).decode())
    print("RESP NT:   " + binascii.hexlify(resp_nt_key).decode())
    print("NT PROOF:  " + binascii.hexlify(nt_proof_str).decode())
    print("KeyExKey:  " + binascii.hexlify(key_exch_key).decode())
print("Random SK: " + binascii.hexlify(r_sess_key).decode())
```

{% endcode %}

Next, we just need to run it with our extracted information and be able to retrieve the session key.

```
python3 calc_smb_session_key.py -u mrealman -d WORKGROUP -p <REDACTED> -n 16e816dead16d4ca7d5d6dee4a015c14 -k fde53b54cb676b9bbf0fb1fbef384698
```

<figure><img src="/files/z20HgxuQe0LsItwB7kNN" alt=""><figcaption></figcaption></figure>

To decrypt the encrypted SMB traffic, we also need the related session ID. This can also be extracted from the `ntlmssp` packet.

<figure><img src="/files/6vBPle41XQoLr7lh3UHT" alt=""><figcaption></figcaption></figure>

Now, we only have to insert the session ID and the calculated session key into the protocol settings at `Edit->Preferences->Protocols->SMB2`. But the option expects a different representation than the one in the packet, as shown below.

<figure><img src="/files/jaLT875DFA5UkDE9oDcN" alt=""><figcaption></figcaption></figure>

After applying the settings, the packets related to the user `mrealman` are decrypted.

<figure><img src="/files/jE5ie4Tw6M9bp9fKiKAP" alt=""><figcaption></figcaption></figure>

We are then are able to extract the transmitted files using `File -> Export Objects -> SMB`.

<figure><img src="/files/YuXvNHCI0AhJTD7R21jf" alt=""><figcaption></figcaption></figure>

In this CSV file, we find the first flag.

<figure><img src="/files/zMiOomoJlFquRXEA0lti" alt=""><figcaption></figcaption></figure>

## Investigation On Second User

### Getting Usernames

Recalling the investigation of the first user, we are able to retrieve the username and all the later necessary information from the `ntlmssp` packet.

<figure><img src="/files/Q2b28q2QfErjsAAUqrfZ" alt=""><figcaption></figcaption></figure>

### Retrieving The Hash

Recalling the hash retrieval from the first user, we were not able to crack the hash, so we need the NTLM hash to decrypt the SMB traffic. For this, we can make use of pypykatz to analyze the LSASS dump.

<figure><img src="/files/3iQb2Hprs5HJwbXZl8J0" alt=""><figcaption></figcaption></figure>

There we will find the NThash of `eshellstrop`.

<figure><img src="/files/ZbXM4F0VE313fGy1eft0" alt=""><figcaption></figcaption></figure>

### Retrieving The Flag

We recall the steps taken on retrieving the flag of the first user and trying to decrypt the SMB traffic of `eshellstrop` to retrieve the transmitted files.

We retrieve the NTProofStr ...

<figure><img src="/files/Za9PCCUlyKtQJdJbk5Ew" alt=""><figcaption></figcaption></figure>

... And the encrypted session key.

<figure><img src="/files/voTPeueLXTPMzH516Bwl" alt=""><figcaption></figcaption></figure>

As already mentioned, we modified the script to also accept hashes, not only passwords. This was a simple modification, since the script just hashed the provided password. We provide the hash via the parameter `-ph`.

```
python3 calc_smb_session_key.py -u eshellstrop -d WORKGROUP -ph <REDACTED> -n 0ca6227a4f00b9654a48908c4801a0ac -k c24f5102a22d286336aac2dfa4dc2e04
```

<figure><img src="/files/8R0MD4HAKboGK2xM3Uxj" alt=""><figcaption></figcaption></figure>

We now then need the session ID of `eshellstrop'`s session.

<figure><img src="/files/lmPsoy6w3oQnQNJ7EFrU" alt=""><figcaption></figcaption></figure>

And repeat the steps as already known of first user.

<figure><img src="/files/AyPXJrNzLQ85LuuIDEW7" alt=""><figcaption></figcaption></figure>

The SMB traffic gets decrpypted.

<figure><img src="/files/VK0wj5TtrMyoS65tTBmX" alt=""><figcaption></figcaption></figure>

We find another CSV file.

<figure><img src="/files/OYOaEgDTq5d6i9jkGpSO" alt=""><figcaption></figcaption></figure>

Which contains the second flag.

<figure><img src="/files/7Lub37oJ16TFkFK53PAP" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xb0b.gitbook.io/writeups/tryhackme/2024/block.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
