Black Cat | Huntress CTF 2023

0xh4lpy
6 min readJan 18, 2024

--

During Cyber Security Awareness Month (2023), I took part in a month-long CTF ran by Huntress Labs, a US-based cybersecurity company. This CTF provided a host of challenges from OSINT to malware. Two of my favourite challenges from the competition were Black Cat and its sequel Black Cat II.

Black Cat

We’ve been hit by the infamous BlackCat Ransomware Group! We need you to help restore the encrypted files. Please help! My favorite rock got encrypted and I’m a wreck right now!

We are provided a blackcat.7z file comprising three files:

  • victim-files/: directory containing the encrypted files (.encry)
  • NOTE.png: the ransom note
  • DecryptMyFiles.exe: a command-line utility which allows us to decrypt

From viewing the ransom note file, we know that the files are encrypted with “MILITARY GRADE ENCRYPTION”:

NOTE.png — BlackCat Ransom Note

As the goal here is to decrypt the files, we are going to be concerned with the DecryptMyFiles.exe binary file.

Performing initial static analysis on the binary with PEStudio, we confirm this is a 64-bit Windows PE (Portable Executable) which has been written using GoLang:

PEStudio — Basic File Information
PEStudio — GoLang Modules

Analysing the file with Ghidra, we see the binary is leveraging an XOR operation within its main function — a logical operation which compares two binary values, returning true if the values differ and false if they are the same.

Ghidra — XOR Encryption

In this instance, the files within victim-files/ have been XOR’d with the key to produce the .encry result.

.decry_file⊕ key = .encry_file

Running DecryptMyFiles.exe, we are given a prompt to enter the decryption key:

DecryptMyFiles.exe Prompt

From some fuzzing, we see that the binary accepts a minimum key length of 8 bytes:

DecryptMyFiles.exe — Key is too small!

Now that we know the key is 8 bytes in length and that XOR is being leveraged for encryption, let’s look at the .encry files to see if we can find any commonality.

Looking specifically at the two encrypted PNG files, we see file signatures match:

Encrypted File Signature

The decrypted file signature for PNG files is:

PNG File Signature [1]

As we now have the decrypted file signature, derive the key by carrying out an XOR operation between the encrypted signature and the decrypted signature:

#!/user/bin/env python3

ciphertext_file_sig = b'\xEA\x3F\x3D\x2A\x62\x68\x75\x63'
plaintext_file_sig = b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'

key = bytearray()

for i in range(len(ciphertext_file_sig)):
k = plaintext_file_sig[i] ^ ciphertext_file_sig[i % len(plaintext_file_sig)]
key.append(k)

print(f'Key is: {key.decode()}')
Key: cosmoboi

Using this key, we can retrieve the decrypted files and the flag:

DecryptMyFiles.exe — Decrypting Files
Flag.txt.decry

flag{092744b55420033c5eb9d609eac5e823}

Black Cat II

Be advised analyst: BlackCat is back! And they’re mad. Very mad. Help our poor user recover the images that they downloaded while browsing their favorite art site. Quickly!

Similar to the first challenge, we are provided a blackcatII.7z file

  • victim-files/: directory containing the encrypted files (.encry)
  • Decryptor.exe: GUI application which enables decryption

Running static analysis with PEStudio, we see this too is a Windows PE, but this time it is written with C# (.NET).

PEStudio — Basic File Information

Opening the binary, we are given two input boxes to supply the path to the victim-files/ directory and the decryption key with ransom note stating that the new encryption algorithm is “UNBREAKABLE”.

Decryptor.exe

Performing the same fuzzing we did with Black Cat I, we see that the key must be 64 characters:

Decryptor.exe — Key must be 64 chars

As this is a .NET-compiled executable, we can get a near-sourcecode representation of the file by using dnSpy (or iLSpy):

dnSpy — Decryptor

As shown above, we have three main utilities within Decryptor:

  • DecryptorUtil: Takes the form input and carries out decryption
  • Form1: Contains the layout of the GUI and form actions
  • Program: Handles the execution of the form

Most notably, within Form1, when the “Decrypt” button is clicked two input checks are made before making a call to DecryptorUtil.DecryptFiles, supplying the victim-files/ path and decryptor key as input.

Form1 — button1_click()

Pivoting to DecryptFiles, the function takes the path to victim-files/, iterates over each .encry file (in alphabetical order), decrypting with AES and the provided key. The files are saved with the .decry extension as we saw in the last challenge.

DecryptorUtil — DecryptFiles()

However, looking at the for-loop, we see that every time a decrypted file is given, the decryption key is the SHA-256 hash of the decrypted file. As the files are read in alphabetical order, the hash of the first file is the decryption key for all files in the victim-files/ directory.

However, we must now find the decrypted version of this file in order to compute the SHA-256 hash. Looking at the victim-files/ directory, five of the files are encrypted JPG’s of famous paintings.

Using OSINT, we can search for websites with these paintings. Eventually, we stumble across an ATX Fine Arts article, titled 100 Most Famous Paintings in the World. From here, we can cross-reference each file with the paintings and confirm that all the files are present.

ATX Fine Arts — 100 Most Famous Paintings in the World

As “A Sunday Afternoon” is the first in alphabetical order, we can download the image to our host and compute the SHA-256 hash for the decryption key:

80d60bddb3b57a28d7c7259103a514cc05507c7b9cf0c42d709bdc93ffc69191

Using this key within Decryptor.exe, we can now decrypt the files and obtain the flag.

Decryptor.exe — Files decrypted!
flag.txt.decry

flag{03365961aa6aca589b59c683eecc9659}

Final Thoughts

As a final disclaimer, during the competition I managed to solve Black Cat I but failed to complete Black Cat II within the allotted time. Despite this, I had a lot of fun reading the different ways in which these challenges were solved and I would encourage you to read these other writeups to further your knowledge [2] [3].

I hope you enjoyed my first ever malware analysis post! More to come!

References

[1] Wikipedia: List of file signatures

[2] HuskyHacks — Huntress CTF 2023 Walkthroughs

[3] GitHub — My Huntress CTF Writeups

Sign up to discover human stories that deepen your understanding of the world.

--

--

0xh4lpy
0xh4lpy

Written by 0xh4lpy

Cybersecurity professional with a focus on digital forensics, incident response, and CTFs. Sharing insightand experience to enhance security knowledge.

No responses yet

Write a response