DownUnderCTF writeups

6 min readSep 20, 2020

There are writeups of some tasks from DownUnderCTF that took place on the weekend.

List of tasks I’ve managed to solve:

  1. [MISC] In a pickle
  2. [MISC] Pretty Good Pitfall
  3. [MISC] Tim Tams
  4. [MISC] Koala Habitat
  5. [Crypto] ceebc

[MISC] In a pickle

We are given the file named ‘data’. There is what we see when we open it:

And that’s exactly what data packed by python module pickle looks like. Besides, there is a hint in the task’s name. So I can load this data like this:

And now I have the dictionary with numbers that look like ASCII codes. So I try to decode it and retrieve the flag:

The flag is: DUCTF{p1ckl3_y0uR_m3554g3}

[MISC] Pretty Good Pitfall

Now we have file ‘flag.txt.gpg’ so it is supposed to be encrypted with GPG. Let’s try to decrypt it:

Well, this one was pretty easy. The flag is: DUCTF{S1GN1NG_A1NT_3NCRYPT10N}

[MISC] Tim Tams

This task could be really challenging. Luckily, I knew exactly what to do with it. This time we were given the audio file ‘Clive.wav’. Let’s open it with Audacity and look at its spectre:

Hey! Isn’t it an SSTV (Slow-scan television) signal? Seems so. I’ve seen this before. Therefore I have Robot36 app on my smartphone to decode it. And here is the screenshot with decoded image:

There is a flag on top of the frame but it seems encrypted with ROT13.

And the flag is DUCTF{HUMBLE_M3M3_10RD}

[MISC] Koala Habitat

This one is pretty cool. We get file ‘gumtrees.wav’. Opening it with Audcacity we can see this:

Not really informative. The only thing you can spot is some kind of dashes in spectrum:

Still they don’t really informative. Playing the sound we can hear a lot of noise, like a broken radio. But also there are some kind of morse code. I assumed that those dashes in spectrum could be footprints of it. Anyway, I can’t decode morse by them as I can’t see dashes and dots clearly. I can’t write the code by listening to it because of all the noise.

Seems like we need to clean up the sound. Luckily, Audacity has noise reduction functionality. First, we need to give it a noise pattern. We must select few seconds of the sound with noise only. There are some spaces without morse code in it:

So I will copy them and add to the end of the sound to collect a few seconds of it. But first I want to amplify morse code to make it more visible. For that, I will split sound into two monotracks and mix into one:

Yes, noise has been amplified too, but we will remove it now, right? Here is a collected noise pattern:

Now to remove noise select ‘Effect -> Noise reduction’ with noise pattern selected and click ‘Get Noise Profile’

After that select whole sound track and go to ‘Noise Reduction’ again and click ‘Ok’. Now the sound is much cleaner:

One more thing we’ve got to do before decoding it is to change spectrogram scale. Clearly, the sound we need is within the bounds of 0–1000 Hz. So go to spectrogram settings and change scale from 0–5525 to 0–1000.

The spectre is still messy but now it is much easier to decode it:

At last there is a code I retrieved. It is not equal to the one I drew on the screenshot. Because even if it seems pretty clear, you need to listen carefully to every code as some dots are almost invisible and sometimes dot can look like a dash.


[Crypto] ceebc

This time we are given the server address and it’s source code: ‘’. Let’s look at the source code.

As we can see, after connection to the server we will get a signature of the message ‘cashcashcashcash’ generated with function sign(message, iv). After that server will ask us to input our message and its signature. And it will check if given signature of the message is correct with function verify(message, signature). And if it is, server will check if our input message is equals to ‘flagflagflagflag’.

In short, we have to input message ’flagflagflagflag’ and it’s signature to get the flag. But hey! The signature is generated by encrypting the message with AES in CBC mode and we don’t know the key. So how can we do that? Well, luckily, we not only know the initialization vector (IV) as it is a last 16 bytes of signature we are given, we also can control it when passing the signature to check. That means we can change the IV our input will be encrypted with. Thus we can make ‘flagflagflagflag’ signature be equals to ‘cashcashcashcash’ signature by manipulating the IV.

Let’s look at CBC encryption scheme to break it down:

Here we can see that plaintext is being XORed with IV before encryption. Therefore, changing IV for different plaintexts we can make cipher to generate equal ciphertexts.

Now in math. Let’s assume:

1. P1 = ‘cashcashcashcash’

2. P2 = ‘flagflagflagflag’

3. IV1 = <original IV to encrypt P1>

4. IV2 = <changed IV to encrypt P2>

5. T1 = P1 ^ IV1

6. T2 = P2 ^ IV2

5. C1 = AES.encrypt(T1, KEY)

6. C2 = AES.encrypt(T2, KEY)

What we need to do is to find such IV2 that C1 == C2. So T1 must be equals to T2. Here is an equation:

P1 ^ IV1 = P2 ^ IV2

And the solution is pretty obvious:

IV2 = P1 ^ IV1 ^ P2

Now we just need to write the script to automate it because server will close connection faster than we can solve it by hand. Here is a script:

And the output:

So the flag is: DUCTF{WAT_I_THOUGHT_IV_IZ_G00D}