Background ๐ฎ ๐
The Norwegian Police Security Service (with the Norwegian abbreviation PST which I'll use for this write-up) is the police security agency of Norway. Following up on their big Christmas CTF advent calendar they now did a smaller CTF for Easter.
The theme ๐ฐ ๐
This time PST added an H in their name and created the imaginary Easter Bunny's Security Service (Pรฅskeharens sikkerhetstjeneste = PHST). PHST's role is supposedly to protect the Easter Bunny's egg basket and core values. Everything happened on phst.no from April 9th to April 13th 2020.
Challenges and solutions ๐
Let's jump straight in. Click on a challenge to expand it.
Expand/collapse all
Challenge
We are told that the Easter Bunny's eggs were stolen and that someone had sent the picture above and that it might contain a clue.
Solution
For this you could use some local or online tool for extracting the image meta data. strings would also be a nice candiate for this. The PNG image description field contains the text CUFG{Qrer_snatre_zrt_nyqev!!}
.
That looks a lot like the output of a Caesar cipher. Using an online tool you can quickly see that the flag is PHST{Dere_fanger_meg_aldri!!}
(="You'll never catch me!!").
We are given a piece of a rebus: bravo = "19de0b5a1eeef635c2b4fec6e7c7"
Challenge
PHST received the above picture. It might show the eggs that disappeared. The challenge is to find something of interesting in the picture.
Solution
This time the information we are looking for isn't hidden in the meta data. The eggs are all coloured, and we see a sheet specifying a number for each colour. The sheet also has a reference to resistor colour code. You have to decode each egg as a 3 colour band resistor. Starting from the top of the top left egg you would first get brown, brown, red. That translates to 1, 1, 2.
Following that logic for all the eggs give these numbers: 112 052 052 115 107 051 104 052 114 051 110 033
The numbers can be converted as an integer array to ASCII: p44sk3h4r3n!
(=leet for The Easter Bunny!). The flag is PHST{p44sk3h4r3n!}
.
We are also given another piece of the rebus: {delta: "03074978df7930e256789cb87ea67358"}
Challenge
The bad guys have been accessing the servers of the Easter Bunny. Tracing them back leads to the address 1F423.com
. We are asked to find out something in regards of the address.
Solution
I was stuck on this for a long time. U+1F423
happens to be the unicode for ๐ฃ (hatching chick). I was so sure the flag was related to this.
However, looking at the DNS records there is an interesting LOC record. Using the command dig loc 1F423.com
or an online tool the following coordinates are returned: 60 47 34.900 N 11 6 3.600 E 0.00m 0.00m 0.00m 0.00m
Pasting the coordinates into Google Maps shows the Hamar Olympic Hall - Vikingskipet. That is no coincident as it every Easter hosts the world's second largest computer party: The Gathering. PST has also used this LAN party for recruitment purposes. The flag is PHST{Vikingskipet}
.
We are given a piece of a rebus: echo: "a3f6ce4eb662e4797a39b"
Challenge
We are told that the threat actor has had access to the network, and we are given a pcap mistenkelig.pcap
showing some of the network traffic. The challenge is to figure out what information the threat actor has gotten hold of.
Solution
Most of the traffic in the pcap is encrypted. Considering how the other challenges could be solved with just using online tools I spent a lot of time trying to find something interesting in the network traffic not looking at the encrypted traffic. That was a mistake.
The encrypted traffic is using TLS. For some reason all parameters for the TLS handshakes for one of the computers are sent to another one (is this the intruder doing this or some crazy network logging?). Wireshark is an absolutely magical packet analyzer that can take these keys and secrets and display the decrypted data sent over the wire. It can also extract all the files transmitted.
It turns out that the document the intruder gets a hold of isn't very exciting, but a PDF with the weather forecast for the mentioned Vikingskipet. The flag is PHST{Weather forecast for Vikingskipet}
.
We are also given a piece of a rebus: $charlie = "664150457e1f2ccc3399"
Challenge
We are given a Python program that controls the physical access to the place of the egg thieves. The challenge is to gain access to the system.
Links
Solution
This one was right up my alley. Though tricky at first it's always fun with a programming challenge like this. The script is pretty neat. It uses emoji input and has a set of operations that these emojis can trigger. Those operations can read input from the keyboard and write output to the screen. In practice we are given a set of input that makes the program ask for a password and tells whether or not it was correct.
It didn't take too long to shortcut the program to make it believe it got the correct input and tell that the password was correct. The problem was that the flag was the password you had to type in, and the flag wasn't directly stored in either the program or the input. So you would need to figure out what input triggered the message telling that the password was correct.
The program uses a few pointers and a stack to store the user input and the output. Playing with the stack I saw that the password had to be 34 characters long. Then the password could be brute forced.
Though it didn't look this pretty when I tried hacking it together to be among the first ones to solve it, here's a cleaned up solution. It requires change in only one line in the initial script as mentioned below. The change makes the program throw an exception the moment it receives either incorrect password length or an incorrect character in the password (starting from the end of the password). This variant of the solution also figures out the password length on it's own too.
"""
NOTE: Add 'raise Exception(sp)' on line 45 in merkelig.py
"""
import sys
from time import time
from string import printable
sys.argv.append('underfundig') # We'll just append the input file here ourselves
password = '#' * 40
def readline():
return password.encode()
sys.stdin.buffer.readline = readline # Quick and dirty replacement of readline()
char_to_change = len(password) - 1
t = time()
while True:
for l in printable:
password = password[0:char_to_change] + l + password[char_to_change + 1:]
found_password = True
try:
import merkelig
except Exception as e:
if e.args[0] != char_to_change:
password = password.strip()
print(password)
char_to_change = e.args[0] - 1 # raise Exception(sp)
found_password = False
finally:
if found_password:
# Prints 'Found password in 1143 ms: PHST{Mitt navn er Gwyn. Pen Gwyn.}':
print('Found password in', round((time() - t) * 1000), 'ms:', password)
The flag was PHST{Mitt navn er Gwyn. Pen Gwyn.}
(="My name is Gwyn. Pen Gwyn."). So just like Pen Gwyn gave NPST a hard time last Christmas, he now has been after PHST.
The final piece for the rebus was this: String alfa = "0c405bdf5899c3db8ba0d1909f9"
Challenge
The challenge was to solve the rebus print("https://www.phst.no/" + alfa + bravo + charlie + delta + echo + ".html")
Solution
We have found all the different pieces of the rebus and we can add them together to get
https://www.phst.no/0c405bdf5899c3db8ba0d1909f919de0b5a1eeef635c2b4fec6e7c7664150457e1f2ccc339903074978df7930e256789cb87ea67358a3f6ce4eb662e4797a39b.html
:
alfa = "0c405bdf5899c3db8ba0d1909f9"
bravo = "19de0b5a1eeef635c2b4fec6e7c7"
charlie = "664150457e1f2ccc3399"
delta = "03074978df7930e256789cb87ea67358"
echo = "a3f6ce4eb662e4797a39b"
print("https://www.phst.no/" + alfa + bravo + charlie + delta + echo + ".html")
The final flag - found on that page - was PHST{Du klarte SHAbussen, veldig bra jobba!}
(="You did the SHAbus, very nicely done!").
By the end of the day of second Easter day 19 people had full score and a total of 24 had solved all the challenges. I was pretty happy being the fourth person to solve the last challenge and therefore placing me on fourth place in total.
Some final thoughts ๐
I really enjoyed these Easter puzzles. They were entertaining, varied and they didn't need that big of a time investment. Maybe the best part was that the challenges were opened daily at 12 p.m. instead of 12 a.m., so there was no need to lose any sleep or check the mobile in the middle of the night.