In this write-up we will be visiting the Crack This! challenge from HackTheBox.
Crack the program and get the flag!
We start off by executing the application to inspect the intended application input/output.
The application appears to be requesting configuration file. Since we do not know the format of the configuration file, we can go ahead and analyze the binary. Since the binary is a .NET executable we use dnSpy to inspect it.
Upon inspection we find that the binary has been obfuscated. We further identify a class named ConfusedByAttribute, indicating that the binary was obfuscated using either Confuser or ConfuserEx.
Based on prior experience, we can identify the obfuscator used as ConfuserEx by inspecting the contents of the <Module> class constructor. Before we can analyze the functionality of the binary, we need to unpack and deobfuscate the binary.
We start by decrypting hidden functions and decoding obfuscated symbols using de4dot as shown below.
We now have a file named CrackThis!-cleaned.exe, which contains a decrypted binary. However, the binary is still heavily obfuscated so we need to deobfuscate it further using some exotic tools. Since these tools may be hard to find online, I have provided a download package with all three of them.
We start off by using the Proxy Call Fixer v2 by Davicore to remove proxy calls and junk methods. This will clean up our binary a bit and allow us to perform string decryption, as these are no longer proxied.
We can now use the ConfuserExStringDecryptor by CodeCracker to decrypt strings used throughout the application.
So far so good. The next step is to use the ConfuserExSwitchKiller by CodeCracker to remove the switch-obfuscation technique used by ConfuserEx. This will clean up our binary nicely.
As a final measure, we will run de4dot again, since de4dot might locate new recoverable symbols that it failed to identify while the application was heavily obfuscated.
The application is now unpacked and deobfuscated, so we can once again open it in dnSpy for analysis.
We start by locating the Main function as shown below.
As seen in the illustration above, we find that the configuration file is just a rabbit hole. Upon launching the application with five command-line parameters we should reach a branch that presents us with a password prompt.
As shown in the illustration above, we are presented with a password prompt. Let’s take a look at how the expected password is generated. As seen in the Main function, our input is compared a value returned from a call to Class7.smethod_1.
Looking at the Class7.smethod_1 function, as shown in the illustration above, we see that the function can either return ‘Thisea$__Sup4H4k@!’ or forward a value returned from Class6.method_2.
Looking at the Class6.method_2 function, as shown in the illustration above, we can see that the function can either return ‘$k4toulaki_0l333!’ or combine string_0 and string_1 from an inherited base class.
Looking at Class5, from which Class6 inherits its base, we can see that string_0 is set to a custom string using the method_0 function and that string_1 is set to ‘admin’ using the method_1 function. We can see in the constructor of the previously shown Class6, that the constructor invokes method_0 with either ‘system’ or S3cr3t_Aidoni!!’ followed by a call to method_1.
Thus we can effectively compile the following list of possible password combinations:
We can now attempt the four passwords, and find that systemadmin is the correct one.
And there you have it – the challenge has been solved!