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.