BlackCat II [Hard]

Writeup from Huntress CTF - BlackCat 2

CTF

11/2/20234 min read

BlackCat II was a tricky challenge, and disclaimer, but I managed to do it in a unnecessary difficult way... (Learned for a fellow peer after the CTF how to do it the easy way), so in this writeup, I will show how I managed to do it the hard way... And how to do it the easier way.

spaceylad@proton.me

The image hunt

Since this is a continuation of BlackCat I, I decided to follow the same logic and strategy as before. I checked the files that has been encrypted and noticed that these are images, not .txt files.. Which was a bit annoying, since plain text files are really easy to read when you have done it right, while images are much more sensitive, 1 byte change, and the image will not show. The first thing I did was to look for the original image files on the internet. This was a bit tricky, but I learned that you can put the original image name into google surrounded with “” and check images, then they will show up.

The link: https://www.atxfinearts.com/blogs/news/100-most-famous-paintings-in-the-world

I right clicked the images that was relevant, used “copy image path”, visited the link and downloaded a image. I noticed that it was “.webp” file format, so I changed it to “.jpg” for good measure. But I could see that the files were the same size, which confirmed our theory that these are the correct images! After scrolling the website, a bit more, I could find the rest of the original images there too.

I had a feeling we could not use the same technique as before, since this is a hard challenge while the last one was a medium, but I gave it a try anyway. Without any success.

Alright! It is time to open good’ol Ghidra and… It is a .NET program… So good night Ghidra and hello there dnSpy!
Going through the program with dnSpy we want to learn what is going on when we decrypt our message. I am not even close to good enough with decompilers to do this myself, so I got help from GPT, as it explained to me what was going on in the decompiled code, every single step. When going through the DecryptorUtil() function, I noticed something strange I have never seen before.

Reverse engineering time!

CalculateSHA256Hash Method: Computes the SHA256 hash of the content of a given file. This hash is used as the key for decrypting subsequent files.”

Hmm… so it decrypts the first file with the give key… Then it decrypts the next file in its list with the SHA256 key of the previous decrypted file… And we have the original files after Dorking our way through the interwebs…

So! What is our battleplan? This is where I was a silly hecker and overcomplicated the task. I decided that I wanted to rewrite the decompiled code, then recompile the actual exe to do what I want it to do! So I edited the original function from this:

To this:

Then I found the SHA256sum of every file by using SHA256sum on Kali and used them in the main decryptor. (I spent a couple of hours trying to do this in Python, but with no luck, I am not sure of there is an internal function that I was not aware of, but I could have done something wrong as well.) I tried out the different keys, and since it only decrypted the flag.txt.encry, I could check the flag.txt.decry for successful plaintext content. After a couple of tries… BAM! We got the flag! I was so happy when I saw this… Brought a tear to my eye…

Now… The easy way… I was chatting with one of my peers after the CTF, and he told me a much easier way of solving the task… Since the program goes through a list, why not remove every file except the flag.txt.encry and just feed it the correct SHA256 key? No decompiling or recompiling needed… No headache of understanding the code… Just getting the flag as it is… Facepalm