At Hurricane Labs, we like to participate in Capture the Flag (CTF) events from time to time. Last month, we participated in a few events including the NahamCon, Hack-a-Sat, and Defenit CTFs. The variety of challenges across these events was diverse, giving our team a lot of interesting tasks to chew on and lose sleep over.
Having recovered from the excitement, satisfaction, and frustration that comes with any good CTF, now is a good time to discuss some of the challenges we encountered and our approaches to solving them. In this three-part series, we're going to cover three different scripting challenges from the NahamCon CTF. So, without further ado, let's open a text editor and put on our coding caps.
It's time for some educational programming! We’ll first look at a 100-point scripting challenge: Big Bird. The challenge description directs us to a Twitter profile owned and operated by Big Bird:
Big Bird is communicating with us in a whole new way! But... how?
Connect here: https://twitter.com/BigBird01558595.
Each of Big Bird's cryptic tweets contains a number and a value. There are a lot of Tweets, but we can download all of them in one fell swoop. For this, I used Twint:
❯ twint -u BigBird01558595 | tee tweets.txt 1266885032754515968 2020-05-30 20:11:44 EDT <BigBird01558595> Tweet #168 12 1266884770623078400 2020-05-30 20:10:41 EDT <BigBird01558595> Tweet #274 72 1266884512681779212 2020-05-30 20:09:40 EDT <BigBird01558595> Tweet #23 111 1266884254790750208 2020-05-30 20:08:38 EDT <BigBird01558595> Tweet #376 63 ...
The tweets are numbered in the form "Tweet #xxx", but they were not posted in this order. Let's utilize the
sort commands to fix this and clean up the above output:
❯ cut -d'#' -f2 tweets.txt | sort -n | tee sorted.txt 0 137 1 80 2 78 3 71 << removed >> 398 66 399 96 400 130 401 0
This shows us that there are 402 uniquely numbered tweets (starting from zero). This is an encouraging pattern.
If we now look at the values that come after each Tweet number, we see that they are all between 0 and 255 (inclusive). This is the acceptable range of values for the byte data type, so we can convert these decimal numbers to the raw bytes they represent. The following script performs this conversion and writes the resulting data to an output file:
#!/usr/bin/env python3 import array # parse decimal values from text file values =  for line in open('sorted.txt'): num, val = line.split() values.append(int(val)) # convert decimal values to bytes, then write them to file bytearr = array.array('B', values).tobytes() with open('output.bin','wb') as f: f.write(bytearr)
file on the output file, we discover that it's image data:
❯ file output.bin output.bin: PNG image data, 111 x 111, 1-bit colormap, non-interlaced
Judging from the image, it looks like the letters of the day are "QR." Here's the image below:
Scanning the QR code reveals:
Part 2 coming soon!
If you're interested in reading more, continue to part 2 of our NahamCon CTF series. This next challenge will also involve some creative decoding.