Writeups – Numbers Game, BabyRE (RCTF – Part 2)

This post continues from my last post on. Two more writeups for RCTF are presented below.

Numbers Game

This challenge was presented as an IP and port, with the clue that we had to “guess”. This challenge ended up being a variation of “Cows and Bulls” (or, if you prefer, the Fallout hacking puzzle). We guess 4 numbers, then are told how many we have in the correct position, and how many numbers have the correct value but are in the wrong position.

A simple Python script solves this cleanly, which you can download here.

Funnily enough, from the Wikipedia article, we note that the minimal average game length is just over 5 turns:

We are provided 6: therefore, our solution must be optimal (fortunately, the solver I found off github was).


This challenge was presented as a Linux binary, which you can download here. While presented as a reverse engineering challenge, I performed only minimal reverse engineering to complete this challenge.

Initial analysis showed that this executable took in some letters and a number, followed by some arbitrary additional input. The output seemed to be a series of dword values. One of what appears to be the encoding steps is shown below:

Based on this alone, I made a few assumptions:

  • The application encoded one character at a time
  • There was no meaningful randomness, despite randomness-based functions being called
  • The order of characters didn’t matter (but this is slightly irrelevant if we have an encoding oracle)

I first tested my hypothesis by providing “test 15” as the first inputs, then encoding “abc” and “cba”. These provided the expected result: that is, one dword value corresponded to each character of input.

I then attempted to encode “RCTF”, which provided dword outputs which corresponded to the contents of the “out” file – I assumed at this point that this was the flag. Further testing confirmed that the order of characters did not matter.

From here, a little bit of Python makes this a trivial solve: we simply encode the entire alphabet, and test this against the “out” file. You can download the script I used here.

Overall, I enjoyed participating in this CTF – this showed me some serious gaps I have with webappsec and pwning. As always, I look forward to improving my skill for the next one.

See you all in “Security Fest CTF” and Faust CTF in two week’s time.

Posted in Jesting, Computers, Bards | Leave a comment

Writeups – Sign, Cpushop, Cats (RCTF – Part 1)

This weekend, I participated in the RCTF event. This was a well-paced, yet challenging CTF – I enjoyed this event, and did not encounter any hosting issues aside from a few moments when one of the web challenges went down.

I learned a few useful things from this CTF, and I will present some writeups below. In an attempt to keep these posts to a somewhat manageable length, I will split these writeups into two posts.


Cats was presented as a miscellaneous challenge: the object was to find 15 commands which were equivalent to “cat”, when “food” was provided as argv[1] (and we controlled the contents of the file “food”). A dockerfile was provided, through which we could run this challenge locally, without a Google ReCAPTCHA slowing us down.

The “check” simply ensured that “cat food” and “$input food” provided the same output and return value, so the obvious choice was to look for equivalents to cat. Initially, I browsed my CTF box, looking for promising binaries. I came up with an initial list:

tail, more, head.

“less” didn’t seem to work in the target environment, so I set this aside. I then changed the file to contain the contents “food”, so “ls” would work, and changed the file to a single line, so commands like “tac” and “shuf” would work. This allowed me a few more options:


For the remainder of the challenge, I started up a Docker environment in AWS, and listed /usr/bin, manually looking for binaries which may have not been present on my CTF box. I ended up with the following list:


Successfully giving me the flag:


This challenge was presented as a Linux executable, which you can download here. The challenge was to run the executable for the flag.

Initial analysis showed that there were a number of strange-looking imports, and structures indicating the presence of a Windows executable. I attempted to extract this Windows executable, and glued a DOS Stub from another functioning Windows executable in, to no effect:

The structures seemed somehow mangled, and the executable would not execute.

At this point, I stumbled across a PNG in the file, which showed the Wine Notepad icon, so I ran the original executable in Wine for shits and giggles:

No shit, it’s the fucking flag. Welp.


This challenge was presented as a Python file, which ran remotely. You can download this here.

Inspecting the file, we note that the application acts as an oracle: that is, you can use it to sign a pre-constructed string (via the “Order” functionality), and then test if any string has a valid signature (via the “Pay” functionality). If we are able to correctly sign a querystring with “product=Flag” and “price=<less than our monies>”, we win.

We note the signature is constructed via the following function:

sha256(key + message)

This is affected by a hash length extension attack, where we’re able to construct a new, valid signature which appends an arbitrary string to the old signature.

In this case, it doesn’t matter what we append, as long as it ends with “&product=Flag&price=4”.

The only restriction is that in order to conduct this attack, we must know the length of “key”: but fortunately, the program limits this to range(8,32), and we are able to brute force.

You can download the Python script I used for this here.

I struggled for a while to get Python to exit properly (that is, for pwntools.recvuntil() to handle cases where the target string is received, and where a flag is printed and there is no target string), so I ended up using Wireshark to grab the flag:

In the next post, I will discuss the babyre and numbers game challenges.

Posted in Bards, Computers, Jesting | Leave a comment

Writeups – ELF Crumble (DEFCON Quals)

In the past weekend, I participated in the DEFCON Quals CTF. I was able to solve three challenges, and I will present writeups for one challenge – I lost another through poor record-keeping, and the third, Eval Whitelisting, is not conductive to a writeup (the solution was to wrap ../flag in backticks in a printf).

ELF Crumble

The ELF Crumble challenge was presented as an archive file, containing pieces of an ELF executable, as well as the file “broken”, containing the executable’s “shell”. You can download the files here.

We begin our investigation with the “broken” file, as it seems to be a valid ELF executable. We can immediately see the problem:

We note that several “core” functions are like this, including f1, f2, f3 and recover_flag. Strings doesn’t reveal anything immediately obvious (and fair enough).

Fortunately, symbols are left intact in the application, giving us the (possible) length of each function. We can also make three assumptions:

  • Firstly, each function will begin with a resonable prologue, such as setting up the stack. No function will begin with some hand-crafted prologue.
  • Secondly, each function will end with a reasonable epilogue, such as a return instruction. No function will end with something odd like a jump.
  • Thirdly, the function fragments will “fit tightly” with one another. There are no overlaps, there are no overwritten sections, there are no gaps where “pop eax” is the actual instruction. This correlates with the file lengths of the chunks.

Following this guidance, we know that only one chunk can possibly fit into the first chunk, f1, and have the function look somewhat reasonable:

From here, I wrote a quick capstone-powered disassembler to show me the first few bytes of each chunk, and quickly reassembled the executable by hand, giving me the flag. You can find the Python script used to disassemble the chunks here, and the final executable here.

I’d like to thank the DEFCON CTF organisers for a well put-together and challenging CTF. Getting rekt each time in this CTF is a good reminder that there are always greater heights to climb, no matter how much we have achieved so far.

At this point, I would like to take a moment to reflect – in the past few weeks, I am delighted to see more and more talented people throwing themselves into the mix and challenging themselves in various ways – not only in CTF’ing, but in tackling various self–sought projects and tasks. With this, comes more people to discuss this work and collaborate with – this brings a modicum of heartfelt joy between the hours of 9am and 5pm.

For those of you who want to get into CTF’ing, there is no better time than now. For those of you sitting on the sidelines, know that there is no progress without sacrifice – try, try again, and never give up. For those of you who have settled and stagnated, satisfied that you know enough to do your jobs and it does not require more: may you find happiness in your own way, living your own life with whatever meaning and purpose you see fit.

Posted in Bards, Computers, Jesting | Leave a comment

Writeup – Pupper (PlaidCTF)

This past weekend, I briefly participated in PlaidCTF. Unfortunately, with other life priorities interfering, I was not able to play the entire weekend, but I was able to solve one challenge in the time available. The writeup is presented below.


This challenge was presented as a package containing source code and a Linux binary, which you can download here.

This was a taint-tracking variant of ML (Meta Language). I had never programmed in ML before, but the syntax appeared relatively simple to work out via the examples. Running the “failing” examples shows the nature of the challenge – we need to reveal a “private” value:

Fortunately, we can leak a single bit of data via an if statement:

From here, it is a simple matter of brute forcing the flag, bit-by-bit. Fortunately, the source code of the challenge lets us know the length of the flag (36 chars):

You can find the Python script used here. The “%d” placeholder. in “fuck.dog” is the value of the variable y.

As always, thankyou to the PlaidCTF organisers for putting together a well-structured and varied CTF. With any luck, see you all in the DEF CON CTF Qualifier, and in FAUST CTF.

Posted in Bards, Computers, Jesting | Leave a comment

Writeups – Babyc, Plastic (ASISCTF 2018 Quals)

Over the past two days, I had the pleasure of briefly playing in the ASIS 2018 CTF Quals with the folks from Monsec. During this time, I solved the “babyc” and “plastic” challenges, both of which I present here for future reference. The “babyc” writeup will be more detailed than usual, outlining methods which did not work.


This challenge was presented as a Linux executable, which you can download here. The challenge text indicated that we only needed the first 14 characters of the input, which gives you a “good” output (that is, ASIS{sha1(input[:14])}). Running the executable lets you enter some user input, after which “Wrong” was printed. Running strings gives us one interesting string (“m0vfu3c4t0r!”) but this isn’t the flag input.

On disassembly, we immediately note that it is movfuscated:

My first attempt involved running strace and ltrace against the executable, to identify at a high level what it actually did. We note that it does a strcmp – a little trial and error shows that the strcmp is against input[3:], and the maximum input is 32 bytes long.

Still, filling this with the magic “m0vfu3c4t0r!” string doesn’t work either, so we’re still missing something.

My first attempt was brute forcing the first 3 characters. I used a simple Python script, shown below:

At this point, I decided to attempt two side channel attacks – firstly, against the return code (from a previous challenge), and then, against the instruction count. Firstly, the return code, as it’s a simpler brute force – I solved a CTF challenge once a long time ago, as it would modify it’s return code for each character of the flag you got right (so you could brute force character by character.

Unfortunately, I wasn’t able to make this produce anything meaningful. My next attempt was to instruction count: that is, using the “perf” program running on a bare-metal box, I could count the number of instructions executed for each given input. Again, a character-by-character brute force attack was attempted:

This produced quite interesting results:

Even on the same box, two different iterations of the script produce different “maximum instruction count paths” for input, indicating that the executable performs the same amount of instructions no matter how many input characters are provided, or how many are correct.

I then resorted to manual analysis, grepping for immediate arguments. Searching on a whim for ‘A’, we get a hit:

A little while later, we can see the same code pattern, repeating with ‘h’:

Scrolling further through the code, we can see a few more characters, totalling “Ah_0y1ng:(“. I wasn’t too sure what to do at this point, and didn’t want to manually spend the time reverse engineering movfuscated logic. I went with my instinct, SHA1’ing “Ah_m0vfu3c4t0r” for the flag and an easy ~100 points.


This challenge was presented as a PNG image, presented below in it’s entirety:

Binwalk showed nothing, and quick pixel analysis showed nothing. I attempted to play around with things like alpha channels, but nothing turned up. Opening the image in a hex editor reveals our first clue:

We can immediately see base64 encoded content. Not knowing what this was, I went to Google “RDF”, which didn’t turn up anything too relevant to this specific challenge. I then went to unbase64 this, providing a blob of binary data: I couldn’t see anything, but binwalk said there was zlib data from offset 4. Zlib.decompress’ing this provides the flag:

Thankyou to the ASIS 2018 CTF Quals creators for putting together this CTF – this was a good set of challenges, and I am learning much from other people’s writeups.

Posted in Bards, Computers, Jesting | 2 Comments