Micro Corruption — The Embedded Security CTF

Micro Corruption’s CTF style challenges are great practice for learning the basics of binary exploitation. The main changeable panel shows 6 main sections, the Disassembly, Memory Dump, Register State, Current Instruction, Debugger Console/Command Line and finally the I/O Console. Challenges, titled with a cities name where the idea is that you are living hacking an embedded lock and hacking the lock completes the challenge.

This article will be a walk through for all of the challenges as I complete them. Generally I’ll be going from easiest to hardest. I will also be giving the most detailed explanations at first and dropping the easy stuff as I go on because theirs nothing I hate more than a tutorial/guide that assumes you know too much on the first intro challenge.

I have actually already completed several of these challenge, but now that I’m deeper into the ‘Practical Binary Exploitation’ book it should be much easier the second time.

New Orleans

Starting with the main program we can see that a password is created, retrieved, then checked before printing “Access Granted” if the password is correct.

You’ll first want to set a breakpoint on the main function with the command before typing ‘c’ to continue

The next point of interest as you step through the program will be the create_password function shown below

So what’s happening here is the first instruction,mov #0x2400, r15, initializes the register location with the following mov.b (move bytes) instructions building up a string in the r15 register. From what I can tell from other guides this is a unique string to every user so don’t try to copy mine!

The final step for this challenge will be to convert the hex to text (Or just type the hex into the box and check the ‘Check here if entering hex encoded input’ box) and solve the lock! (CyberChef for conversions).

To solve the challenge type ‘solve’ in the Debugger Console and type your decoded string to unlock the door!

Sydney

Now for level 2. Things get only slightly harder in this challenge with the main focus being on knowing what Little Endian is. From Wikipedia below:

A little-endian system, in contrast, stores the least-significant byte at the smallest address.

So how is that important for this challenge? Well the answer that is showing up in the Disassembler and the actual typed answer are going to be opposite, but we’ll get to that in a moment.

So to start the program setting a breakpoint at main will work. Here is ‘main’ shown below.

So here we have the same basic format as the previous challenge, you enter a password to unlock the lock before the password is retrieved, checked, and unlocked based on what you entered.

In a slight turn of events if you check out the check_password function you will notice that it only pushes 64 to r14 and calls ‘getsn’.

Following the trace down to ‘getsn’ we can see that it pushes r14, r15, and 0x2 to the stack before calling ‘INT’, yet another new function shown below.

The main function of ‘INT’ is to type the prompt to enter a password before calling ‘__trap_interrupt’ which will actually prompt the user for input and save it to memory at 439c.

The real magic happens in the ‘check_password’ function shown below.

Here’s where the actual password is checked against the input from the user. if you’ll notice there are several cmp followed by a jnz. Cmp is a comparison statement, like 0x3f39 == r15 where the result is either a 1 or a 0. The jnz is a jump if not 0, so in this case it’s a jump if false where 0x3f39 != r15. So if you’re still following, the password is checked in chunks and if any part of it is unequal then it won’t continue.

So the password should just be ‘3f392e7430575225' right? Well no, here the Little Endianness comes in making the actual answer ‘393f742e57302552’. Make sure to check the ‘Check here if entering hex encoded input’ which we want because these are raw hex numbers, the decoded text version is also accepted (CyberChef for conversions).

Hanoi

Hanoi begins a new form of Binary Exploitation, buffer overflows! Buffer overflows are a giant category and take a lot to fully understand, I will be the first to admit that I only understand the basics. My first introduction to Buffer Overflows was via Heath Adams ‘Practical Ethical Hacking’ course, I highly recommend it. Since then I have checked out ‘Smashing the Stack For Fun and Profit’, Vuln Server, and various CTFs.

The basic vulnerability is that when taking user input, it always needs to be validated/sanitized. When it is both not checked and isn’t checked before being saved on the stack, you have a potential buffer overflow. A quick example is shown in the C code below.

The Vulnerability here is on line 6. Doing a ‘strcpy’ command in C without checking how large the input is allows an attacker to execute a Buffer Overflow. In the worst case scenario, that Buffer Overflow can then be combined with some shell code to grant any user the permissions of the parent binary.

Now for this challenge. Right away the instructions remind you that “passwords are between 8 and 16 characters.” which is a good first hint of a buffer overflow. As for the code itself, like normal we start in the ‘main’ function. Sadly, all the ‘main’ function does is call ‘login’

‘login’ starts by asking you to enter the password, reminding you that it has to be between 6 and 16 characters before calling ‘test_password_valid’. I enter 4 A’s as the password

The first half of the ‘login’ function

‘test_password_valid’ as shown below does little more than move some data around. After further analysis I believe it to be dead/junk code meant only to throw an analysis off.

‘test_password_valid’ function

After the return sends us back to the ‘login’ function we see the critical lines shown below.

Second half of ‘login’

Notice on location 455a 0xac is compared to the value at 2410 in memory, well with my 4 A’s this is what the Live Memory Dump looks like,

Memory 2410 showing no data at 2410

This of course does not open the door and the challenge fails, but what if we could fill that memory from 2400 to 2410 with junk data then set 2410 = ac? Shown below is that memory dump with a working input.

Memory filled up to 2410 with ac = 2410

Congratulations on completing your first Buffer Overflow!

Hello! My name's Matt and I'm a self-studing Cybersecurty professional with an eye to work in Reverse Engineering. This blog will chart my progress and work.