This CTF was mainly aimed at beginners with various challenges involving cryptography, steganography, reverse engineering, web exploitation, pwn, and forensics. Let’s get started!
Zip Zap Zoo
We have hidden important information for you in this file. But remember, it's not always about brute-forcing...
We are given a file that you can download below if you want to give it a try:
I know it’s presented as a ZIP file, but I still always start my recon on a file with the file
and TRiD
commands just to make sure. This appears to be a valid zip archive, let’s unzip it. Unzipping it reveals another zip file called file.zip
this time. After checking that it’s a legitimate ZIP file, I unzip it. But there’s a snag!

The file won’t unzip! Is it corrupted? First thing to check is if the header is correct. A quick search on Gary Kessler’s File Signature Library reveals that ZIP files all start by 50 4B 03 04
. Let’s fire up our hex editor GHex
to see what’s up with this file header:

As we can see here, we have 50 4B 08 09
instead of 50 4B 03 04
, so let’s correct this and see if we can unzip it after saving the corrected file:

The file seems to be fixed now because it doesn’t complain anymore about having a bad header, and instead we are prompted to enter a password… except I didn’t see any hint anywhere for a password. I’m about to whip out John the Ripper
or fcrackzip
but then I remember the challenge description: ” But remember, it’s not always about brute-forcing…”. Hmmm… where can this hint be? Re-reading the challenge description doesn’t help. What did I miss? I go back to the initial file, challenge.zip
. What’s so special about it? Just a simple ZIP file that contained a single file. So I pull out my checklist and go through it. And this happens:

That’s what checklists are fore, amirite? AMIRITE? I’ll never learn. Anyway, it was *that* simple. That’s probably the zip password: “hack the stereotypes” in leet speak. Sure enough, this time I can unzip the file out comes flag.txt
. Hurray! I’m that close to getting the flag! Except no:

I drop the string into CyberChef and find that it is Base32 encoding:

Not That Easy
We have intercepted communications between two criminals and we found that they had shared secret information. Can you find the secret?
We are given a file that you can download below if you want to try to solve this challenge yourself or follow along with me:
Opening this packet capture file reveals 175 packets, most of them being DNS queries and TCP handshakes. As usual, let’s try the obvious and just check out the TCP Streams by right clicking on a TCP packet and selecting Follow / TCP Stream:

This reveals that there are 16 TCP Streams in which we find a conversation between 2 people:
Madonna: Hi dude! Wassup?
Ella: I lost the password again bro. Can you send it please?
Madonna: Why don't you understand? It is not safe.
Ella: What's the issue? Why are you getting annoyed?
Madonna: Don't you know about data breach? We have to protect our data from cyber-threats and all other cyber security related issues.
Ella: Fine, I understand. This will be the last time. Send me the password.
Madonna: Okay, the password is shaktictf{fake_flag}
Now obviously that flag is fake, I won’t even try to submit it 🙂 (what if it actually IS the flag?)
The conversation ends there, and then the 16th and last packet contains a binary file:

I’m curious about this file. Obviously it’s a PNG as we recognize PNG data chunks (IHDR = Image Header, PLTE = Palette, IDAT = Image Data, etc.). So I change from ASCII
to RAW
, save the file and open it up:

Time to fire up zbar
! If this barcode and qrcode reader is not part of your toolkit yet, download it from here or install the package: apt install zbar-tools
.

And there’s our flag! shaktictf{sh3_w4s_h0n0r3d_by_3lectr0nic_fr0nti3r_f0und4ti0n}
Hidden
Seems like there is something hidden in this image. Can you find it?

We are given a file that you can download below if you want to try to solve this challenge yourself or follow along with me:
The first command of my steganography checklist (file
command) reveals this:

That comment seems awfully suspicious! And also smells like base64 encoding, let’s give it a try:

The word “passphrase” sounds good when you’re working on a stego challenge 🙂 I know at least one tool that asks for exactly this word, it’s steghide
. Let’s give it a try with this passphrase:

And there’s our flag!
Invisible
One of our engineers got some clues regarding a recent attack in the city, using her knowledge in networking. Can you connect the dots and help us?

We are given a file that you can download below if you want to try to solve this challenge yourself or follow along with me:
Actually the image above was also given with the challenge, but after fooling around with it for a while, everything I tried (strings
, file
, exiftool
, etc.) only resulted in decoding the phrase “Nothing here :(” which was in clear or base 64 encoded.
Turning my attention to the text file, when I display it I see “Nothing here :(” again followed by 12 suspicious blank lines:

This makes me curious about the contents of this file so I try a “cat -A file.txt
” to display any tabs and line endings in the file and this give me a bit more information to chew on:

At this point I see that the file is full of tab characters, and maybe spaces, and I see that not all lines have the same length since the line ending (represented by $) is not always at the same place. Maybe this is Morse code or binary, if I replace the tab characters by “1” and spaces by “0”, or tab characters by “.” and spaces by “-“. I try this out and try to decode the resulting morse code and binary into ascii but nothing humanly readable is output.
Then I remember a technique called snow
. This steganography technique uses spaces and tabs to encode text inside text files so that the message seems invisible to the human eye. One popular piece of software used to encode and decode snow messages is called stegsnow
. Let’s try it out:

This doesn’t help. But then I remember that the message might have been compressed. And in this case I need to add the extra “-C” option:

Now we’re getting somewhere! This is definitely Morse code! I copy/paste it into https://www.dcode.fr/code-morse and this is what I get:

And that’s our flag!
Secret
An American computer network engineer tried to convey something about a breach that happened recently, but we couldn't understand anything. We have a recording of her conversation with us. Can you help us in retrieving the information?
We are given a file that you can download below if you want to try to solve this challenge yourself or follow along with me:
As I listen to this sound clip, I recognize a voice, but it is distorted and needs to be tweaked to be understandable again. I open up Audacity
and start working on it. The voice seems to have a too high bitrate, it sounds like a chipmunk is trying to communicate 🙂 So I reduce it to 16,000 Hz, but it isn’t enough. I reduce it again to 11,025 Hz and this time the rate seems much more human. Of course the challenge makers didn’t want to make this too easy for us so it sounds like the voice is reversed. To reverse a sound clip in Audacity, Select All, then Effects / Reverse. That’s all there is to it!

The person in the clip is spelling the flat character by character: shaktictf{bh15_w45_4n_e4sy_ch4ll3ng3}
Pretty Good
Ever since she got to know about this privacy technique, she believed that this was the best encryption method. Can you prove her wrong by finding out the message?
We are given 2 image files that you can download below if you want to try to solve this challenge yourself or follow along with me:
One thing I’m often guilty of when working on an image challenge is going through with my steganography checklist without even looking at the image! In this case, it’s pretty obvious that I should be trying to solve the QR code, in addition to my usual checklist. Let’s fire up zbarimg
and try to see what’s hiding in there:

This is interesting! The QR code contains a PGP Private Key. This means that we should try to find a PGP Message and a passphrase somewhere hidden inside this same image or the second image.
The only other thing I can find in file1.png
is with zsteg
, which reveals this message trolling me:

Switching my attention to the second file, which features cartoon heroes Tom & Jerry, performing a strings
finds this at the end of the file:

This could be the passphrase we’re looking for, we’ll try it out when we find the message as we don’t really have anything else yet that we can use as a passphrase. Going through my stego checklist, I find the last piece of the puzzle we’ve been looking for by using jsteg
:

We now have all we need to decode the flag! I head to https://8gwifi.org/pgpencdec.jsp and input the PGP Message, PGP Private Key, and passphrase. Crossing fingers for that passphrase to be the good one! Here’s the result:

There’s our flag! But wait a minute… that’s not the right format, it’s supposed to start with shaktictf{. Let’s see if we can solve this with a simple character rotation (Caesar cipher or shift cipher). I write a quick python script to rotate a string 25 times so that I can see all rotation possibilities:
#!/usr/bin/python3
import colorama
from colorama import Fore, Style
string_to_rotate = "fxnxgvpgs{wH5g_qe1ax_z0e3_p0ss33}" # the string to rotate
string_to_find = "skakti" # the string we're looking for (usually flag prefix)
for i in range(1, 26):
output_string = ""
for s in string_to_rotate:
new_s_ord = ord(s) + i # apply the step increment to each character
if ord(s) in (range(97, 123) or range(65, 91)):
if new_s_ord > 122: new_s_ord -= 26
output_string += chr(new_s_ord)
else:
output_string += s
if string_to_find in output_string: print(Fore.BLUE)
print(output_string)
if string_to_find in output_string: print(Style.RESET_ALL)
Here’s the output when I run this:

There’s our final flag: shaktictf{jU5t_dr1nk_m0r3_c0ff33}
There’s just a small error in the second character that appears as a “k” instead of a “h”, not sure where that came from.
Just Crack It
One of our Network Security Analysts intercepted communications between some spies from other countries and concluded that they used two images to transmit the message. Can you help us?


We are given 2 image files that you can download below if you want to try to solve this challenge yourself or follow along with me:
Applying my usual stego process to these 2 images didn’t bring up anything. So I go back to the challenge name and description, and the name “Just Crack It” seems to suggest that we need to brute-force something. The only thing I can think of right now is brute-forcing steghide
with stegcracker
. I run stegcracker
on laptop.jpg
using the default rockyou.txt
wordlist:

After 5 minutes I still have nothing so I decide to try the other file, hacker.jpg
:

This time, after only a few seconds, the passphrase for hacker.jpg pops out: november
Time to extract whatever this image is hiding:

Pretty sure this new password (14ms0c00l!
) is the passphrase to extract whatever is hiding in laptop.jpg, let’s try it:

And there’s our flag, shaktictf{y0u_M4d3_iT_85284501}
Rail Mail
Joan received a secret mail from her friend, upon looking into it, she found that it contains encrypted text and sum of key and offset. She is clueless what to do. Help her get the message. Email content: Ciphertext: aAknhk{w_319stf333o!itsmpG}c0_ Key + Offset = 11
The word “Rail” in the challenge name is of course a hint related to the Rail fence cipher, a form of transposition cipher that you can read about here. Knowing that CyberChef has a Rail fence recipe, I enter the cipher text in the interface and play around with the key and offset values to always keep the sum at 11, and after a while I find the correct values to display the flag:

There’s an encouraging flag, shaktictf{Aw3s0m3_k33p_Go1n9!}
3, 2, 1… GO!
Introducing our theme woman : "Joan Clarke!" Cipher : WEQEXFTUXQHVOUFPSVLPTORHAFBQE Looks like I found something I shouldn't have. Separate the words by underscores ('_') and submit everything in lowercase around the flag format.

We are provided with the challenge description and image above. If you’ve already competed in CTFs, you know straight off the bat what this image is about. German words, rotors, reflector, alphabet ring… everything points to the Enigma machine used by the German army to encode messages during WWII.
Also, if you’re familiar with the very useful dcode.fr website, you’ll recognize their UI. So I simply went to this website, entered the encoded message and configured the simulated Enigma machine to match the settings in the given picture, and this is what turned up:

Since the challenge description mentioned that we needed to chop up the solution and add the flag prefix, this was an indication that we were looking for a string of non-separated words, which is what we found: YOUHAVECRACKEDTHEENIGMAGENIUS
So we have our flag, it’s shaktictf{you_have_cracked_the_enigma_genius}
Ancient Warfare
Do you know how people from Caesar's time used to send encrypted messages? Try to get the flag : funxgvpgs{byq3e_1f_a0g_nyj4lf_gu3_o3gg3e!}
This is an easy one as it immediately mentions Caesar, so of course the solution will be the Caesar cipher, also known as ROT13. In this case, we know it’s a ROT13 cipher type (vs. ROT47) because we already have the curly braces {} and ROT13 only rotates lowercase and uppercase characters, leaving the special characters in place. So we know that we shouldn’t use ROT47 because we would get rid of the curly braces in this string, which we need!
Another thing to keep in mind when dealing with rotations is that we are not always presented with text that needs to be rotated exactly 13 times. So it’s useful to verify all the possible rotations. For example I’ve written a quick (and not fully optimized) Python script to display all 25 possible rotations:
#!/usr/bin/python3
import colorama
from colorama import Fore, Style
string_to_rotate = "funxgvpgs{byq3e_1f_a0g_nyj4lf_gu3_o3gg3e!}" # the string to rotate
string_to_find = "shakti" # the string we're looking for (usually flag prefix)
for i in range(1, 26):
output_string = ""
for s in string_to_rotate:
new_s_ord = ord(s) + i # apply the step increment to each character
if ord(s) in (range(97, 123) or range(65, 91)):
if new_s_ord > 122: new_s_ord -= 26
output_string += chr(new_s_ord)
else:
output_string += s
if string_to_find in output_string: print(Fore.BLUE)
print(output_string)
if string_to_find in output_string: print(Style.RESET_ALL)
Here’s the output:

And there’s out flag! shaktictf{old3r_1s_n0t_alw4ys_th3_b3tt3r!}
Note that you can also use dcode.fr to brute-force all ROT13 rotations of a string:

And you would have seen the solution immediately by using the ROT13 recipe in CyberChef, but where’s fun in that? 🙂

Wooooww
Some terrorists implanted a spy microphone in our office and tried sending some important project details to their country. The ENIAC programmers caught that and we need your help to extract the secret message.
When I listen to this audio clip, I hear chipmunk-style voices (which could mean that I need to reduce the rate to understand the language more easily), DTMF tones, some music, Morse code, and various sounds.
Just to make sure I’m not missing anything, I run the following commands on the audio file: file
, TrID
, strings
, exiftool
, binwalk
, but don’t see anything special.
Since we hear Morse code in the audio, I decide to try Morse Code Adaptive Audio Decoder first, since it’s easier than solving DTMF tones (to me at least). So I loaded the mp3 file in the site’s interface and hit the Play button. Can you see the flag appear?
Yep, that’s right, the flag is shaktictf{LOLMORS3I5FUN}
Thank you to the Shakti CTF team for putting this event together!
If you have any comments on how I could have solved any of these more easily, please let me know in the comments below so that we can all improve together!