KoreanCTF 2017 : CSHARP Write-Up

Hi people

Starting a blogspot by reversing a .Net PE sound weird to me, but I need to start somewhere :p

This a Write Up about a Korean CTF challenge, the one is named CSHARP It’s not really hard (because of .net) but I found it interresting

MD5 : E8B0B5173B14D118FFD687D37F1A6F06

What I used :

  • DIE (Detect It Easy)
  • DNSpy

Part 1 : Post analyse

The first thing to do is identify what is this PE

It’s look like a .Net assembly (like in the title)

Before reverse anything, I like to see what the tool look like

The typical .Net assembly icon confirm us that it is .Net

Ok so a classic check, a textbox and a message box of answer

So, let’s get started

It’s .Net so I will use dnSpy to decompile it

Nothing special, the Module entrypoint is empty, the Main entrypoint is normal and just launch the Form1 class

So let’s jump in the Form1 class

In imports, we can see something interesting, the System.Reflection library is used to manage assembly in general, so we will have to deal with assembly manipulation.

To begin, I will check for the constructor

Something is done here 🙂

The "MetMett" function fail to be analyzed by dnSpy, so I assume that is encrypted

By analyzing the constructor, we can see that the raw IL instructions bytes of the "MetMett" function is stored in the bb variable

And we see a modification applied to this buffer, we can presume that the modifications decrypt this buffer, we will see latter

The InitializeComponent and Form1_Load functions doing nothing special so I will jump directly to the check button function

So when we press the check button, the textbox input is passed in the "MetMetMet" function, the message box answer doesn’t appear to be here so the "MetMetMet" function do all of the check

So the "MetMetMet" function is a little bit too tight, so I will analyse it step by step

First thing we see is the input password converted to base64 and stored as bytes

After the function create a Dynamic Assembly in memory, create a class called RevKrT1 and define a function called "MetMet" in it

The function creates a second module in memory, create a class called RevKrT2 and define a function called "MetM" in it

The method "MetM" is writed with the bb variable seen above, so we was right 🙂

The "MetMett" function stored the encrypted method, it is decrypted at start and stored in bb variable, and after, it is writen in memory as the "MetM" function

After that this function is Invoked from the second module (RevKrT2) and use the input base64 bytes in arguments.

And here we are 🙂

After the call of the decrypted function, we have the answer of the validation. This means that the previous called function is the check for the password

The crafted "MetMet" function in the first module (RevKrT1) generate manually the IL instructions of the message box

And finally the message box function is called from the (RevKrT1) module

So what we know from here :

We learn that the "MetMetMet" function craft two dynamic modules, one which check the password (MetM)

And one with the messagebox of validation (MetMet)

Part 2 : Running the assembly

So now we have a good idea of what the executable do

I’m going to put two breakpoints One after the modules creations and "MetM" method definition And one after the definition of the messageBox, to see if we are right

When the first breakpoint hit, we see the modules in memory

I will continue to the second breakpoint to see how the code look like I directly jump in the modules from memory

We see the code 🙂

From that we have just to reverse the check function

The password in base64 should be 12 characters, and like we said before, if the array[0] is set to 1, the password is wrong

The check is not difficult, just xor and cmp, so easy to make a reverse script

Conclusion :

It was not difficult but it used uncommon obfuscation techniques (create modules and store decrypted functions in this module) this change of traditional Control Flaw Obfuscation. I found it really fun and it’s why I made a writeup about it.

~r0da