Crab Rave [Hard]
Writeup for Huntress CTF - BlackCat 1
CTF
11/2/20234 min read


Crab rave was rough. Reading this writeup, it may seem like this was a easy “scout and decrypt” task, but believe me when I say that this took way too many hours… I spent 2 days… At least 9 hours in total beating this task, even when I picked the “Easier” variant. But to be honest, this forced me into the world of reverse engineering DLLs, so I am very happy with the outcome! And that I managed to beat it at all is a great achievement in itself. But without further ado! Let’s jump into the writeup!
Understanding the files
When opening the tasks, we are represented with 2 files. “company_financial_report_SAFE_NO_VIRUSES.csv.lnk” and “ntcheckos.dll” (Which we can clearly see in the Linux distro, but Windows by default hides the name extension and hidden files. I always have these visible).
When I concatenate the “.lnk” file, it is clear that this csv is running something much more exciting than a financial report.
“C:WindowsSystem32cmd.exe'..........WindowsSystem32cmd.exe�/c ping -n 1 127.0.0.1 > nul && ping -n 1 127.0.0.1 > nul && ping -n 1 127.0.0.1 > nul && ping -n 1 127.0.0.1 > nul && ping -n 1 127.0.0.1 > nul && C:WindowsSystem32rundll32.exe ntcheckos.dll,DLLMain C:WindowsSystem32imageres.dll�%SystemRoot%System32imageres.dll%SystemRoot%System32imageres.dll”
It seems to be running the system32 cmd.exe, pinging itself… But also using the ntcheckos.dll -> DLLMain function. But what is the DLLMain function doing? Let us boot up good’ol Ghirda and have a look.
I decide to run Ghidra in my guest Windows OS (Because before I ran Ghidra, I ran a Wireshark,ProcMon and RegShot check, but found nothing interesting.) I start a new project -> Import the file and let Ghidra analyse everything. This took a while, so I made a cup of coffee meanwhile.
When it was done, I remembered the DLLMain funcition that was called, so I search it up in the “Symbol Tree” window. A few different ones appeared, but after checking them out, I found one leading to NtCheckOSArchitecture(), and inside this function, we found a crab_rave function… Which is the same name as the CTF task… Curious…


This is sadly where my Reverse engineering skills comes to an end, and I had to ask GPT to help me understand what is going on in the “crab_rave::litcrypt_internal::decrypt_bytes” function. It explained to me that the function is using XOR and the key, shown in clear text to decrypt it. It proved it by making a short PoC (After I managed to get the “&DAT_103cd950” content (By double clicking it), which I used further to explore the other. It could be bullshitting me for all I know, but I also know that this technique worked for me later.


Exploring deeper into the NtCheckOSArchitecture(), I found “crab_rave::inject_flag()” and stepped into that. Inside this function, after lurking around here for a while, I found the “litcrypt_internal::decrypt_bytes” again, but this time with new bytes being decrypted. GPT helped me getting the hex values from “DAT_103cd840”, and I used the context from the decompiled program to put together the last pieces


We found.. 60% of a full link! I could ask GPT to try to fix the hex again, but visiting the URL without the URI was enough to find the content.


Now I just need to decode/decrypt this string! To do this, I dug deeper into the program and looked for anything that could hint on how the string is decoded the intended way. I found AES being used and a curious string to it… (I am very embarrassed to say that I spent hours understanding how this was used, until I realized that the first 32 bytes are the key, the rest is to throw you off).






I found a template Python script for decrypting the AES in CBC mode (And again… I managed to get plenty of errors since the message was not UTF-8, almost stopped trying this, thinking it was a new rabbithole) but then managed to print the raw bytes and VOILA! THE FLAG!!
Ghidra time!





