Projects Posts
15 January 2021 (Updated 31 January 2021) ·
18 min read
CompClub CTF 2021
I had the exciting opportunity to volunteer to help run a security workshop and write an accompanying CTF for high school students!

I’ve been looking for the opportunity to do some form of high school outreach program for a while, so when CSESoc’s (my uni’s constituent society for computer science related degrees) CompClub decided to take applications for workshop developers, and saw the option for a security workshop, I knew I had to sign up. The following CTF was the result of my work with the help of a few fellow fantastic volunteers.

La table des matières

Behind the scenes

While I’ve had the opportunity to write CTF challenges for UNSW Security Society over the past year, and hope to write plenty more this year, this was the first time when I’ve been responsible for getting the CTF infrastructure up and running, and deploying challenges.

If you’re interested in how I did this, particularly if you’re a CompClub workshop developer from the future and trying to figure out how to run a CTF, the README I wrote up in this repo should help you out.

The source code for all the challenges, as well as their writeups can be found there too!


The CTFs I’ve written for in the past have ran for at least 4 hours, and at most 2 days. Writing a CTF with essentially a 2 hour time constraint was one of my main challenges. Another was catering to a variety of experience levels while remaining within the time limit. I also had to avoid OSINT challenges which involved trawling social media, since I couldn’t make the assumption that all students had access to social media.

Challenges and solutions

Here are all the challenges! The solutions are hidden until you click on them, so that you can try challenges without spoilers.


A strange shift (30 points)

Worked two different shifts in one day at Maccas, and I’m too tired to decode this. This dude kept ordering a Chicken Caesar Salad, and uttering this strange code. Can you decode it for me?




The most obvious hint here is the reference to the Caesar cipher, further confirmed by the use of the word shift. However, we could try all 26 possibilities here, and none of them would result in a coherent FLAG.

The sneakier part that you may not have caught in the wording is the ‘double shift’ - two different Caesar shifts were used.

One thing we can note is that we can expect the message to start with FLAG. If we try to rig a shift so that we get the first letter to be F (+13), we get:


Interestingly, this also gets the A in the right place, giving us F_A_.

Shifting to get L in the second position (-5) gives us


This time, we also get the G in the right place! This suggests that there are two alternating shifts.


Taking alternating letters, we get our flag.



compclub (30 points)


compclubcompcompcompclubclubcomp compclubcompcompclubclubcompcomp
compclubcompcompcompcompcompclub compclubcompcompcompclubclubclub
compclubclubclubclubcompclubclub compclubclubcompcompcompclubcomp
compclubclubclubclubcompcompclub compclubcompclubcompclubcompcomp
compcompclubclubcompcompclubclub compclubcompclubclubclubclubclub
compclubclubclubcompcompclubclub compcompclubclubcompcompcompclub
compclubclubclubclubcompclubcomp compclubcompcompcompclubcompclub
compclubclubcompcompclubcompcomp compclubclubclubclubclubcompclub



We seem to have the strings ‘comp’ and ‘club’ as base units here - this seems very much like a binary system!

There also seems to be exactly 8 comps or clubs in a group, or exactly a byte! This suggests that the FLAG could be encoded in ASCII.

We know that all ASCII characters represented as a binary byte start with 0. Since all the groups start with comp, we can guess that comp is 0, and club is 1.

Replacing, we get,

01001100 01000001 01000111 01111011 01100010 01111001 01010100 00110011 01011111 01110011 00110001 01111010 01000101 01100100 01111101

Converting these into their ASCII characters, we get our flag.



Shooting Stars (35 points)

found this cool book about shooting stars! i love shooting stars. the index fell out though.

Remember to wrap your answer with FLAG{}!

book.txt index.txt



The name of the file index.txt hints that the numbers in its contents could be some way that we could index the book, just like we index lists/arrays when programming.

We can see the numbers occur in pairs, (a, b). The a values can get pretty big, while b is always relatively small (at most, 6). This suggests that the second number could be some way of indexing a character within a word. Maybe the first number could be the index of the word we’re using?

We can also see a couple of 0s occurring in the index, for example, the second pair is (0, 0). This suggests that both words and characters are zero-indexed, just like lists and arrays in most programming languages start counting from 0.

This is what is known as a book cipher. You could either try manually calculating each of the letters, writing a script to do it, or using a website like this one to decode it. You’ll need to convert all the index pairs to match the format on that site. Make sure you select the correct options (word number, character number, none), and set the numbering start to 0. Once you do this, you should get your flag.



Other notes

The contents of the book are actually the lyrics to Shooting Stars by Bag Raiders.

An actual flag (50 points)

Was bored, decided to colonise a new planet. Wanted to incorporate the planet name in its flag design - can you find it?

Remember to wrap your answer with FLAG{}!




Typically with an image challenge, I would go through

It’s certainly worth checking through these if everything else fails, but this is a crypto challenge, not a forensics challenge. The wording of the challenge also suggests that the name being hidden in the flag is intrisic to the flag design itself, and not the file.

At this point, we can analyse the colours in the image - there are three of them:

It’s worth noting this image looks really dull. Breaking each of the colours into their subpixels (or bytes):

We can see that none of the bytes are greater than 7F, which is equal to 127 in decimal. This suggests that the colours may be being used to encode ASCII values.

If we convert each byte to their corresponding ASCII values (remember to use the hexadecimal column on the ASCII table), we get

revealing the flag.




firednd-0 (25 points)

Hello! CEO of FireDnD here! We’re a small startup that aims to connect people together for games of Dungeons and Dragons. You can check out our (incomplete - more on that later) website here!

If this website is down, you can find the source code here.

I’ve got a few tasks for you to complete, but before we start, could you do me a favour?

I’m supposed to meet up with someone after work today. I finish at 5PM, and take 8 minutes to walk from my office to Platform 2 of the nearest1 station. I then need to catch the next T4 train, before I get off at the second stop. Can you figure out what time I get off the train (rounded to the nearest minute)?

Your answer should be a 24-hour time. For example, if your answer is 6:04PM, enter FLAG{1804}.



This requires some minor intelligence gathering:

  1. Note that FireDnD’s offices are located at 33-39 Hunter Street, Sydney. This can be found on the site’s footer, or ‘Contact Us’ page.
  2. The nearest station can be found using the measure distance tool on Google Maps - this is Martin Place station - however, it only barely beats out Wynyard station.
  3. We are told that the CEO wishes to take a T4 train from Platform 2 - if you chose Wynyard Station earlier, this is a big clue that something may have gone wrong, as no T4 trains pass through Wynyard. Avid train nerds may also note that Wynyard doesn’t have a Platform 2, as platforms there are numbered from 3. T4 trains on Platform 2 of Martin Place station run eastbound towards Bondi Junction. Two stops in this direction takes us to Edgecliff station.
  4. We now want to check the train schedule for T4 trains departing after 5:08pm on Fridays. The next train would leave at 5:12, and is scheduled to arrive at 5:16:30pm, making the answer 5:17pm, or 17:17.


firednd-1 (30 points)

CEO of FireDnD here again!

Quite recently, I had to fire my frontend web developer, because they were doing a terrible job, as you can probably tell from our incomplete website. I’m still in the process of removing all traces of him from our current website. Your first task is to find a picture of our fired frontend team member, as I haven’t deleted it from our website’s resources yet, but I can’t find it for some reason.

Good luck!



Typically when I’m solving a CTF challenge which involves trying to find some hidden resource on a website, I’ll open the ‘Network’ tab of my browser, and start recording the requests the browser is making. These requests can tell me, for example, what images the browser is loading in - a fair initial suspicion would be that the browser is loading this image of the fired team member, but not displaying it.

However, this isn’t quite the case. If we visit the /team.html page, we can see that three images are being loaded in: team-1.jpg, team-2.jpg and team-4.jpg. The glaring omission of team-3.jpg suggests that this might be our missing file. Visiting /team-3.jpg gives us our flag!



firednd-2 (30 points)

No way, it’s me, the CEO of FireDnD again!

My fired frontend developer hid a secret webpage on our website. I found out about this cool way to prevent search engines from finding the page, so I used that to prevent the page from showing up. I also replaced the contents of the page. Surely no-one can find it now, right?



The first big hint in this challenge comes from the ‘cool way to prevent search engines from finding’ part - this is the exact function of robots.txt. If we visit /robots.txt, we find the following:

User-agent: Googlebot
Disallow: /ry4ns-s3cret-p4ge.html

We’ve now got the URL for the secret page! If we pay it a visit, however, we get this:

Hi! CEO of FireDnD here! I have taken over Ryan's secret page after firing him. That being said, I heard that nothing is deleted from the internet forever. Surely no one has a copy of the old contents of this page?

Unfortunate. Except, not really, because every internet historian’s favourite tool, The Internet Wayback Machine at web.archive.org happens to conveniently have a copy of the page!

There’s an unloaded image on this page. Looking at the source code, we see

<div class="container">
    <h1>Ryan's top secret page</h1>

    <p>Hello, I'm Ryan, a developer at firednd. This is my secret page!</p>

    <p>Here is a secret:</p>
    <img src="/web/20210106050020im_/http://firednd-syd.web.app/FLAG{hiDD3n_in_the_s0uRce}"/>

giving us our flag.




simplelogin (30 points each)

When I grow up, I want to be a software developer at NASA. I’m still on my way to getting there. I decided to practice my web development skills and make an unbreakable login site. I bet you can’t hack me - I’ll even tell you that my username is astronaut.

Good luck!

Challenge source code

There are three flags that can be found at the above link.

Flag 0 has three parts to it - you’ll have to find each part (labelled 1/3, 2/3 and 3/3) and join them together to get the full flag!

Flag 0 solution


(Replace Ctrl with Cmd on macOS.)

This first (well, zeroth) flag requires you to view the page source - that is, the code used to render the webpage to you - to look for comments. The flag is split up across three comments in three different files:



Flag 1 solution


(Replace Ctrl with Cmd on macOS.)

CTF authors like to involve cookies in challenges somehow, and this includes me! Using Ctrl+Shift+I on Chrome and selecting the Application tab, and then ‘Cookies’, reveals all cookies set by the current site, including the flag!



Flag 2 solution


You probably tried to login before anything else, but this is in fact the final flag! Logging in with incorrect details gives us the following message:

‘Password did not match expected encoded result: aXJlQUxMeUxpa0VzUGFjZVNoaVBzMjA3JA==

This looks a lot like base-64 encoding - the biggest giveaway is the occurrence of equal signs on the end (which has a 2/3 probability of happening with base-64). Googling for a base-64 decoder gives us plenty of results, and decoding it gets us the password to use with the username ‘astronaut’ - ‘ireALLyLikEsPaceShiPs207$’. Logging in will give you the flag.

You can also decode base-64 on a Linux command line with echo 'aXJlQUxMeUxpa0VzUGFjZVNoaVBzMjA3JA==' | base64 -d.




Spotify (20 points)

i made my spotify look pretty do you like it

Your flag will be a number. Wrap the number with FLAG{} - for example, if the number is 42, use FLAG{42}.




I tried to hints for this one in plain sight - taking a look at the two recent search items shows you a song named ‘Multiply’ and another named ‘Resolution’ - resolution is a term to describe how many pixels tall and wide an image/video is.

From multiplying the resolution of the image (887 x 606), we get our solution.



Other notes

I made my Spotify look pretty using Spicetify with this theme.

Blank Space (30 points)

i love to listen to Taylor Swift while stargazing. here’s a picture I took, but my camera was broken




In the workshop slides, I highly suggested getting either Photoshop or GIMP to use - however, this was entirely solvable with just Microsoft Paint.

I set the background of this image to #ffffff - this is the hexadecimal code for the colour white. I then used the paintbrush to hide the flag to #fffffd - a colour that is extremely close to white, but not quite, making the writing seem basically invisible.

When solving image challenges for CTFs like these, I typically use Photoshop:

  1. Open the Levels tool from Edit > Adjustments > Levels
  2. Mess around with the input level sliders, and then the output level sliders and see if something reveals itself.

This would’ve worked perfectly well for this challenge. However, a simpler solution would be:

  1. Open the image in Microsoft Paint.
  2. Use the Fill bucket tool, and select a colour like black.
  3. Click somewhere close to the border of the image, ‘flooding the image’.

Paint only fills neighbouring pixels with the exact same colour - this should’ve revealed the off-white writing.



Other notes

Yes, this flag was a reference to the misheard ‘Starbucks Lovers’ lyrics from Taylor Swift’s Blank Space.

Egg nog (50 points)

It’s hard to find egg nog after Christmas. It’s also hard to find my hidden message, I hope!

eggnog.jpg steggnog.png



While this challenge uses a set of techniques that are relatively common in CTFs, paying attention to the workshop slides would have helped a lot here.

The first image you want to look at is eggnog.jpg - note that the contents featured in both images are basically identical, although the PNG is of much lower resolution. Looking at the file’s metadata, we can see that there is some hidden information in the EXIF data (JPG files can have EXIF data, PNG files don’t) - namely, the following string:


We shall save this for later use.

The second image is named steggnog.png - a huge hint that more advanced image steganography, like least significant bit steganography, might be in use here. Googling ‘online steganography’ yields this website. sDecoding it yields the following:


This is the point where this challenge now becomes more crypto than forensics - we can see the result of our steganography decode looks almost like a flag. This is where we go back to our older string - jocksfindquartzglyphvexbmw. Googling this string yields a result about ‘perfect pangrams’ - sentences with all 26 letters of the alphabet exactly once. You might notice that this perfect pangram makes a perfect key for a substitution cipher.

Decoding the substitution cipher (using the perfect pangram as our ciphertext alphabet) on a website like this gives us our flag.



Other notes

The reason the PNG was lower resolution was so that your computer didn’t die trying to decode using the steganography tool - fewer pixels means less work.


Slides (10 points)

Here are the slides from today’s workshop. It comes with a free flag!



Find the slide about what CTF flags are - it’s in plain sight!



What was that? (25 points)

Houston, we’ve got… a disappearing black hole??

Make sure that the FLAG{} contents are all in lowercase.




This challenge features the distinctive short and long flashes (or dots and dashes used in Morse code). Fortunately, there’s also synced beeping noises with the video, which makes interpreting the Morse code a lot easier (although you can just use the video, too!):

  1. Open the audio from the video in an audio editor like Audacity.
  2. Use the spectrogram to identify where each short (dot) flash or long (dash) sound is, and enter it into a Morse Code translator, and voila!


starlang (30 points)

I made my own programming language called starlang! It’s pretty self-explanatory. Can you figure out what this program prints?

(Make sure to open the file with a text editor so that you can read its contents.)




This challenge uses a fake, but straight-forward ‘programming language’ - this is what we call ‘pseudocode’, which is a simplified notation to describe how a program or algorithm should work.

There are some things that you might need to be careful for here:

if (a) {
} else if (b) {
} else if (c) {
} else {

If b is true, then it doesn’t matter if c is true as well - once we’ve completed do_something_else(), we skip to the end of the entire if statement structure.

Following through each of the statements should get you to the flag.




On the day, we received 928 attempted flag submissions amongst 54 competitors in 10 teams, of which, 127 of submissions were correct.

Thanks to all the students that came along and participated in workshops and the CTF! I hope to see you all next year, when we can hopefully actually run this event in person.

Also a shoutout to all the CompClub team, workshop developers and mentors for such a fantastic week, as well as all the random people I’ve asked to test my challenges over the past 2 weeks!

  1. Nearest by straight-line distance. The location of a station can be determined by the position of the ‘T’ logo on Google Maps.