Directory

Do you have what it takes to crack this case? - by hadrian3689

The following post by 0xb0b is licensed under CC BY 4.0


For this challenge, we are provided with a PCAP file. We first analyze it using Wireshark. Based on the SYN requests and the RST-ACK responses from 10.0.2.74, we can quickly tell that a port scan has taken place.

The first 3610 pakets are related to the port scan, after that we can discover some HTTP traffic.

What ports did the threat actor initially find open? Format: from lowest to highest, separated by a comma.

To answer the following questions, we try to use TShark. TShark is the commandโ€‘line network protocol analyzer companion to Wireshark, capable of capturing, decoding, and filtering packet data directly in a terminal.

The question now is about the open ports that the attacker has found. Means, that we get an answer via SYN ACK response indicating an open port.

We use the knowledge from our first insight via Wireshark that the scan extends to packet 3610 and limit the analysis to this.

The -c option in TShark specifies the number of packets to capture or read from a file. With -c 3610 tshark will process only the first 3610 packets from the traffic-1725627206938.pcap file. Once it reaches the limit of 3610 packets, it will stop processing. We filter TCP packets where both the SYN and ACK flags are set -Y "tcp.flags.syn == 1 && tcp.flags.ack == 1", and print only each packetโ€™s TCP sourceโ€‘port field -T fields -e tcp.srcport. We then sort the ports numerically, removes duplicates, and outputs the unique list as a single commaโ€‘separated line | sort -n | uniq | paste -sd ','.

tshark -r traffic-1725627206938.pcap -c 3610 -T fields -e tcp.srcport -Y "tcp.flags.syn == 1 && tcp.flags.ack == 1" | sort -n | uniq | paste -sd ','

The threat actor found four valid usernames, but only one username allowed the attacker to achieve a foothold on the server. What was the username?

We skip the Nmap traffic and scroll down the traffic shown in Wireshark, until we reach packet no. 4667, there the KRB5 traffic starts. From this traffic we can potentially extract the username that allowed the attacker to achieve foothold.

Scrolling down to 4679 we see an error for PREAUTH_REQUIRED.

We see some authentication attempts resulting in unknown principals errors. The errors stop occuring after packet no. 4785.

On packet no. 4817 we don't see any error after an AS-REQ and could extract the username here.

Solving this task with TShark we check the fields available to extract related to kerberos.

tshark -G fields | grep -i kerberos

With the following command we extract every matching packet containing the Kerberos client principal name string kerberos.CNameString and its realm kerberos.crealm. We assume the last entries are the ones, that made a successful login.

tshark -r traffic-1725627206938.pcap -Y "kerberos" -T fields -e kerberos.CNameString -e kerberos.crealm
tshark -r traffic-1725627206938.pcap -Y "kerberos" -T fields -e kerberos.CNameString -e kerberos.crealm | awk 'NF==2 {print $2 "\\" $1}'

The threat actor captured a hash from the user in question 2. What are the last 30 characters of that hash?

What we are looking for is an encrypted message or blob of information, not a hash, that is used by Kerberos for authentication. The AS-REP is an encrypted packet, not a hash. It is encrypted using AES, RC4, or even public-key cryptography (PKINIT).

Marjan Sterjev had pointed out my post on LinkedIn regarding this topic, and I agree with him that we should use precise terminology. Thank you, for your clarification!

The requested information is contained in the packets that transmit the kerberos.cipher. Filtering these packets will allow us to extract the last 30 characters.

tshark -r traffic-1725627206938.pcap -Y 'kerberos and kerberos.CNameString == "larry.doe"' -T fields -e kerberos.checksum -e kerberos.cipher -e kerberos.CNameString -e frame.number

We extract the frame number too, and see that the blob was transferred in the packet before 4817.

Next, we just extract kerberos.cipher field from the last request...

tshark -r traffic-1725627206938.pcap -Y 'kerberos and kerberos.CNameString == "larry.doe"' -T fields -e kerberos.cipher | tail -n 1

... and use AWK to print the last 30 characters of the blob.

tshark -r traffic-1725627206938.pcap -Y 'kerberos and kerberos.CNameString == "larry.doe"' -T fields -e kerberos.cipher | tail -n 1 | awk '{print substr($0, length($0)-29)}'

What is the user's password?

While researching about KRB traffic, we came across the following resource:

It is depicted there how to use the following script to extract any AS-REP ciphers transferred in a PCAP file. Unfortunately, this is no longer available.

But we get an alternative here:

After we have converted the pcap file as described and used the pdml file with the script krbpa2john.py , we have not received any output. We were only able to partially reconstruct the Kerberos cipher using the krb2john.py script provided by John, the user@domain.com was missing. We already got that information - see question 2. We can already see that it is a Kerberos 5, etype 23, AS-REP blob.

The following TShark attempt shows how to reconstruct it manually. We can extract all the required information with the command below.

tshark -r traffic-1725627206938.pcap -Y 'kerberos and kerberos.CNameString == "larry.doe"' -T fields -e kerberos.CNameString -e kerberos.crealm -e kerberos.sname_string -e kerberos.checksum -e kerberos.cipher -e kerberos.info_salt | tail -n 1

To reconstruct the required format by hashcat to crack it, the second part of the kerberos.cipher field is relevant.

tshark -r traffic-1725627206938.pcap -Y "frame.number==4817" -T fields -e kerberos.cipher

We use AWK to combine everything into the format required by hashcat.

tshark -r traffic-1725627206938.pcap -Y "frame.number==4817" -T fields -e kerberos.cipher -e kerberos.CNameString -e kerberos.crealm | \
awk -F'\t' '{split($1,a,","); print "$krb5asrep$23$"$2"@"$3":"a[2]}' | \
awk -F':' '{prefix_len=length($1) + 33; print substr($0, 1, prefix_len) "$" substr($0, prefix_len+1)}'

Next, we crack it using rockyou.txt.

hashcat -a0 -m18200 directory.hash /usr/share/wordlists/rockyou.txt

What were the second and third commands that the threat actor executed on the system? Format: command1,command2

After the authentication of larry.doe we see traffic on 5985. Port 5985 is used for Windows Remote Management - WinRM, indicating remote command execution or administrative access after authentication.

However, the traffic is encrypted.

After a short research we come across the following tool for decrypting winrm traffic. This is possible for us, as we have the user's password.

Unfortunately, it throws errors.

python3 winrm_decrypt.py -p 'REDACTED' ../traffic-1725627206938.pcap

In the description of the repo we see a reference to a fork. We try to use that instead.

We run the script from the fork and are able to decrypt the traffic. We directly write it to a file.

https://gist.github.com/jborean93/d6ff5e87f8a9f5cb215cd49826523045/

python3 winrm_decrypt.py -p 'REDACTED' ./traffic-1725627206938.pcap > decrypted_traffic.txt

When scrolling through the decrypted traffic, we recognize a schema. The commands are base64 encoded in arguments tags.

We extract them and write them to a file.

grep -oP '(?<=<rsp:Arguments>).*?(?=</rsp:Arguments>)' decrypted_traffic.txt
grep -oP '(?<=<rsp:Arguments>).*?(?=</rsp:Arguments>)' decrypted_traffic.txt > encoded_arguments.txt

Next, we decode each argument.

while read line; do                                                     
  echo "$line" | base64 --decode >> arguments.txt
  echo "" >> arguments.txt
done < encoded_arguments.txt

We find the first command: whoami

To make it more readable we use grep. And now find all commands made including the flag.

grep -a '<S N="V">' arguments.txt | awk -F'[<>]' '{print $3}'

What is the flag?

grep -a '<S N="V">' arguments.txt | awk -F'[<>]' '{print $3}'

Recommendation

Marjan Sterjevs version of the script does not need password or nt_hash:

https://pastebin.com/u2jCceRX

If -e is specified on the input, the script will try to:

  • process the WWW-Authenticate and Authorization NTLMSSP Negotiation messages

  • crack the password with John The Riper and finally

  • decode, process and output the string content of the WinRM messages; it looks for RSP CommandLine content and the associated response streams.

https://www.linkedin.com/posts/marjansterjev_directory-activity-7353043871032827904-3vc1?utm_source=share&utm_medium=member_desktop&rcm=ACoAAEQHbzcBmjOtd0QWGGhWpdy2mzZ2j-geKp8

Last updated

Was this helpful?