So there was pretty cool CTF held on the past weekend. There were plenty of great tasks, here are solutions to some of them. Tasks “Break Me!” and “treasure” require detailed explanations, so I will write separate stories for them.
- General Skills Quiz [MISC]
- rabbit [MISC]
- nostrings [Reverse]
- Retro! [Forensics]
- How to pronounce GIF [Forensics]
- Do the loop! [Forensics]
- deadcode [PWN]
- Leaking like a sieve [PWN]
- Substitution Cipher I [Crypto]
- Break Me! [Crypto]
- treasure [Crypto]
General Skills Quiz [MISC]
This one is pretty easy one, although a bit annoying. We have the server address, and when we connect to it, we are asked to solve a few simplest tasks in 30 seconds. Well, clearly, we can’t do that without automating this. Annoying part is that we don’t know all tasks we have to solve ahead of time. So we must write script step by step. The final script run is on the picture below.
And the script itself:
We are given the file
flag.txt, but when we open it, we see the binary data
file utility says that this data is compressed with
bz2. So when we decompress it we get another compressed data. It is pretty obvious that we have to automate the decompression process. But we also should consider that there are other compression methods could be used. So what we do is we try to decompress it with
bz2 and if we fail, we print the hex of data and stop. After determining what data do we have, we can add another compression method and run again from this point. This way here is the script I got:
Here I check the first two bytes of the data to determine the compression signature, so I can use right decompression method. And I stop as soon as I find unrecognized signature.
This script stops with this data
The data length is pretty small to be the file, so I fed it to CyberChef
Looks like base64
For this task we have an ELF file. What we should do is open it in IDA, and find the flag
Double click on it and here we go
This time we get the image
To find the flag we have to just use
exiftool on it.
How to pronounce GIF [Forensics]
We have the GIF animation.
It seems like it contains QR codes, but we can se just one part at a frame. We can use
stegsolve to split the give by frames. There are 120 of them. I saved all of them.
stegsolve I determined, that there are 10 different QR codes:
- First, because there are 10 different colors.
- Second, because every 10 frames we clearly see step down.
Now, I have 120 parts of QR codes. I don’t want to glue them together by hand. So I need wrote a script:
After running this script I have 10 QR codes. One example:
Now, I also don’t want to decode them by hand (yeah, I am lazy), so I wrote bash script for that:
Script returns a lot of useless text, except of highlighted two parts of base64 string. We can concatenate those and decode to get the flag
Do the loop! [Forensics]
Sound this time. And there are clearly Morse codes in it.
We could easily decode that, also there is a problem. There is a lot of noise, so sometimes it gets pretty hard.
So let’s reduce the noise. For that I take end of the audio file, where there are no codes, and use it as noise pattern.
Now, I can select all audio and reduce noise
And now there are much less noise
Anyway, there left a part where it is still pretty hard to say what is a dot and what is a dash.
So I repeat reduction with noise pattern in between two codes
Still not perfect, but I can live with that. So the Morse code string is:
-.-. --- ..- .-.. -..
.-.. .. ... - . -.
- .... .. ...
.-.. --- --- .--.
.- .-.. .-..
-.. .- -.--
And the decoded is (which is also the flag):
This task is a simple buffer overflow exploitation. We have an ELF, let’s look inside with IDA
Here we see, that we are asked to enter some string, and after we input it, the program checks if the OTHER variable has some particular value (which it didn’t have before), and if it does we get access to the shell. But it uses
gets() function to read the user input, so we can enter any amount of data, and at some point overwrite any data that is placed “under” our input buffer in stack. I won’t go into details here, you can easily find the detailed explanation on how BOF attacks work somewhere else (there are plenty of good materials on that). Let’s just exploit it.
We can calculate amount of data to overflow the buffer with variables stack offsets:
24 bytes it is. So after we enter 24 characters, we will fill all space between the beginning of the input buffer and the variable we want to overwrite. Next 4 bytes we write must have particular value:
deadcode in hex. Also do not forget that values are stored with little ending byte order, so we should write it backwards.
First, we make local solution, to check if we get everything right. The script is
Running it we get the shell
And let’s modify it for the remote connection
And here we go
Leaking like a sieve [PWN]
This one is also a PWN task with well known vulnerability — namely, format string vulnerability. Let’s look inside the
We can see, that our input is fed directly to the
printf() function. Again, I will not explain the details, but we now can use that fact to get the flag. What we also should notice, is that the flag is somewhere on the stack also, cause it’s being read into
To exploit that, we don’t even have to write the scripts. We just connect to server and feed it the string
And the server sends back it’s current stack. Now, let’s analyze the highlighted part.
First, we remove some values we don’t need — addresses, and our input value.
We now left with something that looks like the flag.
We remember that the values are stored in little endian, but we want them in big endian, so we reverse them. And finally decode the hex to get the flag.
Substitution Cipher I [Crypto]
For this task we have a source code file that performs flag encryption. Also we have the output.
When we read this script carefully we can see that it basically just calculates the formula
x is a single character code and
y is the encrypted character. So obviously all we have to do is solve quadratic equation for every encrypted character.