RE Series #5: exrs 1-7

Written in

by

A write up for the challenges posted here: https://github.com/wapiflapi/exrs

I’ve only done r1-r7, and I’ve yet to do r8 and r9

R1

As straight forward as running “strings” on the binary

R2

Some dynamic analysis is involved. We run the program through IDA, and breakpoint at the string comparison to see what it’s comparing to

R3

Static analysis with Ghidra. We open the binary and let Ghidra decompile the function for us

R4

A small step up in the difficulty, we have to analyze the code to see what value the loop stops at.

The flow pass if “check_password” returns 0

for test EAX EAX to jump, it means EAX must be 0

We can simulate inputs to the binary in IDA under “Debugger->Process Options->Parameters”

The loop checks the input against multiple strings, and if it matches, it checks if the counter value is equals to 539h, or 1337

Checks for the value 539h

We let the program run until EAX == 1337, and look at the string it’s comparing against. We do this by setting a breakpoint, and editing the Condition

Set a conditional break for the flow to be EAX == 1337

When we let the program run and break on 1337, we find our required string:

I don’t even drink

R5

The binary checks for an input string length to be 28h, or 40, if not it exits the program

The program proceed to do some complicated operations on our input string, and compares the final output the string “this_aint_that_simple_but_good_luck_haha”

Complicated morphing operation
Comparing the morphed output with this string.

When we try different inputs, the output is always deterministic. We can thus try to deduce the ASCII shift of our input string by taking the difference between the input ASCII and the output ASCII. Using this difference, we apply it to “this_aint_that_simple_but_good_luck_haha” to reverse what string is required to be inputted.

python3 solution

R6

Static Analysis with Ghidra shows that the length of the input needs to be 21 characters long

We observe that local_10 is being returned, and this needs to be 0 at the end of the operation so that “password OK” may be printed.

This also means that local_19 needs to be 0 on each loop, so that local_10 will never be incremented. (Since it’s unsigned, we can’t minus any values)

We convert the code above to python for simpler analysis

Python3 equivalent

looper is called 3 times, but if we look at what it’s doing, its XORing local_19 43 times with the input string of length 21. This is equivalent to XOR-ing the string with itself with the exception of the one character of our input string. This means that on each iteration, local_19 is XORed by 1 character of our string, and since looper is being run 3 times, 2 of it will cancel itself out, which means it’s only XORed once.

The final operation at index 0 would therefore be:

input_19 = input_19 ^ key1_list[0] ^ key2_list[0] ^ input_string[0]

For input_19 to be 0, key1_list[0] ^ key2_list[0] ^ input_string[0] need to be 0. Therefore, to figure out input_string, we just XOR key1 and key2 together (As shown in the bottom)

R7

R7 is pretty straight forward. We open it with Ghidra to see this function happening

MD5_Init, MD5_Update and MD5_Final are all part of the MD5 hashing operation. Simply put, it takes out string, generates an MD5, and checks it with -0x71a6158f5f87a14, or 0x8e590ea70a0785ec, and -0x430566d217348d26 or 0x0bcfa992de8cb72da.

local_c0 is the top half of the MD5 string, and local_c8 is the bottom of the MD5 string. Because the stack grows downwards, we need to reverse the hex values. The final MD5 string we need to obtain is: ec85070aa70e598eda72cbe82d99fabc

Throwing this to any cracker online, we get the flag to be: md5password

Closing Thoughts

This set of challenges showed that “Reverse Engineering” isn’t just about looking at assembly code, but to understand the logic behind what a program is doing, and how to figure out the right input. No patching is meant to be done, and the flag can be found purely by analysis.

Perhaps I’ll try r8 and r9 someday, but as there are no solutions posted, and given my stubborn nature, I fear I may be stuck on those problems for a long time, which will be detrimental to my learning. In my next set of challenges, I’ll be focusing more on cracking here: https://crackmes.one/

Thanks for reading!

Tags

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: