Malwarebytes CrackMe - contest summary

Malwarebytes CrackMe – contest summary

On October 29 we published our third CrackMe Challenge and announced two parallel tracks for the contest: “The fastest solve” , and “The best write-up“.

In the first category (“The fastest solve” ), we got three winners already the first weekend following publication. Big congratulations to:

🥇 @nazywam

🥈 Suvaditya Sur (@x0r19x91)

🥉 @evandrix

Yet, even those of you who are not as fast could still join in the fun, and get a chance to win a prize in the second category. Submissions for the best writeup closed November 12 (two weeks after the Crackme publication). In this post we will summarize the writeups that we received, and announce the winner for the best writeup!

Hall of fame

The submissions were treated as valid if they contained the following flag:


We received them in the following order:

  1. 🥇 @nazywam
  2. 🥈 Suvaditya Sur (@x0r19x91)
  3. 🥉 @evandrix
  4. 🎊 Alex Skalozub (@pieceofsummer)
  5. 🎊 @JLeow00
  6. 🎊 rainbowpigeon
  7. 🎊 arm4nd0
  8. 🎊 Matthieu Walter (@matth_walter)
  9. 🎊 Bahlai Vladyslav (@BaglaiVlad) & Alex Shevchuk
  10. 🎊 @kasua02
  11. 🎊 @zvikam

Congratulations to all the solvers!

CrackMe 3 challenge

Before we present you with the writeups, let’s have a quick look at the task itself.

The CrackMe was composed of multiple components:

  • The GUI application (written in .NET): responsible for taking the input, and verifying it / passing it to the further layers. It was accepting 3 passwords for the consecutive levels.
  • The server: a native application, packed. Responsible for verifying the input of the passwords for the stages 2 and 3. Communicating with the GUI application with the help of a named pipe, and a local TCP server.
  • The DLL injector (written in .NET, loaded into the main application with the help of .NET Reflection)
  • The hooking DLL: a native application, injected into the server and hooking some of the used APIs, changing the password verification function.

It is worth to note that each level of the CrackMe depends on the previous one, so the passwords have to be provided in the right order.

To make the analysis easier, and more approachable for beginners, the code (apart from the loader part) was not obfuscated. Some components were based on public code, or contained debug strings making it easier to follow.

Level 1:

In the first level, the user was supposed to input the password that would let the second stage get properly decoded and run as a new process. The second stage of the crackme was a PE, steganographically hidden in the image that was displayed in the GUI, and obfuscated by XOR with a static key. The key could be cracked with the help of plaintext attack.

Level 2:

The second password inserted by the user was sent over the pipe to the previously deployed server. The user was supposed to unpack the core of the server, and analyze it. First, it was required to notice that the presence of certain analysis tools cause the crackme to exit. Then, the user needed to find out that the expected password is in reality the name of one of those analysis tools. The next step was finding a public list of suspected tools, and cracking the password by a dictionary attack.

The correct password was not only clearing the level, but also triggering the decryption of the hooking DLL, that was injected in the server.

Level 3:

The third password inserted by the user was sent over the local TCP connection to the previously deployed server.

The user was supposed to notice that the hooking DLL alters the behavior of the verification function. With this information, the actual flow of the verification function should be reconstructed. Then it was possible to crack the final password.

Techniques covered:

  1. Steganography
  2. Packed executable (loader with self-injection of the payload)
  3. Shellcodified PE
  4. Loading functions by hashes (API hashing)
  5. Basic anti-analysis tricks
  6. Vectored Exception Handling (VEH)
  7. Inline hooking
  8. Inter-process communication
  9. .NET Reflection
  10. Classic DLL injection

List of writeups

We received 6 writeups in total, from the following contestants:

Scoring the writeups

As we mentioned in the contest opening:

The write-up will be judged by its educational value, clarity, and accuracy. The author should show their method of solving the CrackMe, as well as provide the explanation of the techniques used in the challenge

Just like in the previous edition, in order to introduce some objective measures, several categories were used to assign points.

  • The quality of the solution:

There are no wrong solutions if they lead to the goal. However, some approaches are faster and more elegant than others. We ranked higher the solutions that are straight to the point and not over-engineered. If multiple solutions were presented in a single writeup, we appreciated if the author stated which of them is the most optimal, and why.

  • An in-depth explanation of the inner workings of the CrackMe, guiding through the process of solving. This means writers should have:
  1. Explained how to approach the CrackMe: presented an overview of the task as a whole
  2. Explained each stage of the CrackMe: the main logic, relationship to the other levels
  3. Identified and described each executable layer the stage was composed of (loaders, shellcodes, etc.)
  4. Identified each algorithm used (i.e. CRC32, RC4)
  5. Identified and explained each technique used (from the list “techniques covered”)
  6. Explained the third verification function before and after hooking, presented what each hook is responsible for, and how it changes the logic

An educational value of the writeup. Writers should have:

  1. Introduced tools before they were used, showing the environment setup
  2. Provided detailed explanation of the used techniques, reaching beyond the CrackMe itself. For example, providing links where the reader can learn more.
  3. Described the solution in a comprehensive way, that can be followed by a beginner
  4. If applicable, presented different approaches, and explanation which of them is the recommended one and why
  5. Provided graphical illustrations making the provided explanation easier to follow. Diagrams, GIFs, videos, etc.
  6. Been especially clear and had a pleasant writing style

You could also get some bonus points for OSINT if you found:

  1. The header of the payload in the stage 2 was shellcodified with the help of pe_to_shellcode
  2. The hashes in the stage 2 were based on the list from the Al-Khasher project
  3. The function checking the processes was copied from the repo: antianalysis_demos
  4. The hooking DLL was created with the help of MS Detours, and based on the following template

The writeup contest results

All 6 solutions turn out to be of very high quality, so it was extremely hard to select winners. Even trying to introduce some objective criteria for judging writeups, all authors covered most of the points that we would like to see described, and the margin between the scores was small. That’s why we decided to reward all of them with Malwarebytes swag.

Additionally, we decided to distinct three, most comprehensive solutions, that will be rewarded with the main prize (an IT-related book of contestant’s choice):

  • rainbowpigeon [ writeup ] – clear explanation of the stages, elegance and simplicity of the taken approaches
  • Matthieu Walter (@matth_walter) [ writeup ] – detailed explanation of each level, easy to follow even for a person who didn’t solve the crackme themselves
  • @JLeow00 [ writeup ] – for the efforts to provide an educational value: detailed explanations, diagrams

All the authors will be contacted soon!

Once again thank you for participation, and hopefully see you again next year!