Writeups – Slumdog Millionaire, Purple Posse Market, Matroichka 1,2 (Nuit du Hack Quals)

Last weekend, I had the pleasure of once more participating in the Nuit du Hack qualifier CTF. Similar to last year, I found this to be an enjoyable event, even though my lack of skill and focus meant I was not able to solve many challenges. As always, I will document some of the interesting challenges I encountered.

I should note that from here, I will make an attempt to tackle web-based challenges, as this is an area that I am particularly and notably weak in.

Without further ado:

Matroichka 1

As last year, a four-part matroichka reverse engineering challenge was presented in this year’s CTF. You can download the original binary (as well as an unpacked Part 2) here.

I began my analysis by loading step1.bin into IDA Pro. The first challenge was a string comparison check, with a few distraction functions (“mmm”, “you” and “touch”). The core of the functionality is here:

A quick breakpoint at 0x4007A0  reveals two things:

  • Our input string is reversed, and;
  • The “target” string is Tr4laLa!!!

Running the program with an argument of “!!!aLal4rT” (appropriately escaped, of course) quickly revealed the second part of the binary, which is detailed below.

Matroichka 2

This binary is included with the download for Matroichka 1. Alternatively, just run Matroichka 1 with the correct flag, and this binary will be printed on stderr.

Again, I began my analysis by loading this binary into IDA Pro. This revealed a far more complex binary than the first:

Judging by the structure of the program, this did not appear to be an angr-style solve, so I delved further into the program. After some analysis, the structure of the program became clear:

  • Firstly, the program checked if argv[0] was “./step2.bin”. This would prevent the program from running correctly under gdb, as well as if it was incorrectly named.
  • Then, the program utilised a strange chained block cipher (utilizing simple XOR) along with some signal handler trickery to check the key.

Firstly, in order to overcome the argv[0] check, it was sufficient to re-write argv[0] at program execution, with the following steps:

  • break *0x4007CC
  • set {char[12]} $rax = “./step2.bin”
  • c
  • break *0x400879

Following this check, the program then checked if the first character of the flag (entered in argv[1]) was “W” (at 0x40085C). From here, the real “meat” of the program begins:

Immediately noticeable is the use of signal() to install a signal handler, as well as the unusual use of the “cmovz” instruction to select which signal handler is installed (either 400AC6 or 400AD0).

In a nutshell:

  • for each letter of our input:
    • if it’s even, subtract it’s value from the next character, mod 256 (and replace the next character with this)
    • if it’s odd, add it’s value to the next character, mod 256 (and replace the next character with this)

Following this, a static block of data (divided up into dwords) is then chain XOR’ed with 0xDEADBEEF: that is, 0xDEADBEEF is the xor key for the first block, the xor’ed first block is the xor key of the second block, and so forth. This slightly enciphered block is then compared with our mutated input (as above).

Due to the predictable nature of this algorithm (and that we know the first character of the key, “W”), we can quickly derive a Python script to work backwards: that is, we first reproduce the XOR code, and then we work backwards to derive what each character of the flag is.

You can download the solution script here.

Slumdog Millionaire

This challenge was presented as a web challenge, along with an associated Python file, which you can download here.

The website appeared to represent a lottery website: you could enter a set of random numbers, and the site would tell you if you guessed correctly or incorrectly (and print the correct set of numbers). The Python file above provided the algorithm behind the lottery game:

The algorithm appears to have a single point of failure: that is, the random number generator is seeded once – once you know the random number, the actual number generation isn’t very random.

The attack against this is a simple brute force search against the random seed used: given one set of winning numbers, we can easily determine the random seed, and thus predict the next set of numbers.

You can download the brute force solution script here.

Purple Posse Market

This challenge was presented as a raw web challenge, appearing to represent a legitimate web business. The purpose of the challenge was to determine the administrator’s IBAN number (think bank account):

After browsing the site for a few moments, we hit gold with a contact form:

Experience says that this is a cross-site scripting challenge: I quickly spin up a requestb.in bucket, and try submitting a few contact forms. After a few tries (input filtering?), we get lucky, and end up with an administrator cookie:

From here, it is simple to read the /admin site with an administrator cookie, and retrieve the administrator’s IBAN number, for an easy 200 [?] points:

As always, I’d like to thank the Nuit du Hack organisers for putting together another enjoyable event, and I particularly look forward to solving the remainder of the Matroichka challenge, as time permits (level 3 is a fork-based mindfuck).

See you all in the ASIS CTF this weekend.

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.