Writeup – Matroichka 1, 2, 3 (NDH)

This weekend’s Nuit du Hack provided 4 reverse engineering challenges which were required to be solved in order. I got through 1, 2, and 3 with a minimum of effort, but number 4 was the reverse engineering equivalent of the EVE Online learning cliff:



I’ll present my writeup of challenges 1, 2 and 3, as well as some notes on 4 which I was not able to solve during the time-frame allocated (another blog post – am keen to work on during the week).

Matroichka 1

Matroichka 1 is a warmup-grade challenge: opening it in IDA immediately reveals the key:

strin... nevermind.

strin… nevermind.

Entering this key spits out a base64 encoded output, which turns out to be the level 2 executable.

Matroichka 2

Matroichka 2 is a slightly more difficult – firstly, strlen() is performed against the key to ensure it’s the right length – instead of comparing the result of strlen against the correct answer, strlen’s return value is obfuscated as follows:

.text:0000000000400747 lea rdx, [rax+1]
.text:000000000040074B mov rax, rdx
.text:000000000040074E shl rax, 2
.text:0000000000400752 add rax, rdx
.text:0000000000400755 shl rax, 2
.text:0000000000400759 add rax, rdx
.text:000000000040075C add rax, rax
.text:000000000040075F cmp rax, 1F8

This can be trivially brute-forced, or you can simply undo the maths (it’s not that difficult) – or if you own a copy of the Hex-Rays decompiler, I suppose you could just press F5.

There’s a whole stack of these checks, and they all look like this:



All of these checks are executed in order, and if you fail a check, [rbp-14h] is set to 0. A little bit of pen, paper and Python reveals the key to be “Pandi_panda”, which then gives you the third binary.

Matroichka 3

Matroichka 3 is a little more complex: immediately, we notice heavy use being made of the “_signal” function, and an odd “_kill” loop which tries to terminate the current process with a SIGSEGV:

creative, but easily visible in ida

creative, but easily visible in ida

Note that we’ve already got a signal handler set by “_signal”: therefore, when we give the process SIGSEGV via _kill, the SIGSEGV handler is executed.

The handler looks like this:

20 something of these little shits

20 something of these little shits

Note how it sets a new signal handler if the check (0x40083F) succeeds.

In a nutshell, the application tries to send 0x3FF SIGSEGV kills to itself – if it succeeds in handling one SIGSEGV, it sets the “next” signal handler. If a check fails – well, the new signal handler is simply never set, the process sends all 0x3FF signals to itself then exits.

Unlike Matroichka 2, manually reverse engineering this was annoying enough that I built a brute-force thingy.

From here, it’s simply a matter of taking each signal handler, sticking the maths part (after mov eax,[rbp+var_4], to mov eax,edx) into the brute force shell and letting it run: the “correct” result ends up in eax, which you can view in a debugger. Half an hour later, we get the key (“Did_you_like_signals?” – yes I did, this was an enjoyable diversion) and the stage 4 binary, and the fun really begins…

holy fucking shitballs

holy fucking shitballs

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Bards, Computers, Jesting. Bookmark the permalink.

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 )

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.