Few weeks ago I prepared the technical background of the CTF (Capture the Flag) for QuBit Conference Sofia 2019. It was intedned as a contest in which the three most successful participants will get the opportunity to attend QuBit Conference Sofia 2019. The content itself consisted of 10 challenges divided in 5 categories. In this post will be sumarized the thoughts, ideas and hints about the intended ways how to solve particular challenges.


The abovementioned five categories was Forensics, Crypto, Stego, OSInt&Recon (Open Source Intellingence and Reconnaissance) and, of course, Miscellaneous. In my opinion The Misc category this time was interesting because there were different aproaches how to solve the challenges, from Puzzle solving to Reverse engineering of slightly exotic platform (Arduino). Now, lets dive into each category and challenge.


Pcap Analysis (20 pts., 22 Solves)

Task was to analyze the provided Pcap file http.pcap and find the flag. The Pcap contains only few packets, starts with DNS lookup of the domain qubit-ctf.baco.sk (the domain of the CTF itself) following with HTTP request for URI http://qubit-ctf.baco.sk/blah/flag.png). If you tried to visit this location during the contest,you saw only the picture with message “You are late. Sorry.” This was not so easy, the file flag.png had been changed before the contest. We need to extract the original one from the Pcap. We can follow the HTTP Stream (Right Click on HTTP packet -> Follow -> HTTP Stream) and extract the content of the PNG picture. Or, more easy, just export the HTTP objects (Menu -> File -> Export Objects -> HTTP …)

Fig. 1: PNG picture in http.pcap

GPG Message (30 pts., 15 Solves)

The participants were provided with disk image (1 MB FAT drive). This drive contains two files: public key for address qubit-ctf(at)protonmail(dot)com, and encrypted message, probably zipped text file due to extensions:

$ ls -l 
total 4
-rwxr-xr-x 1 root root  651 sep 13 23:00 message.txt.zip.gpg
-rwxr-xr-x 1 root root 1797 sep 13 23:00 publickey.qubit-ctf@protonmail.com.asc
$ file *
message.txt.zip.gpg:                    PGP RSA encrypted session key - keyid: 5821BE00 E37B5B05 RSA (Encrypt or Sign) 2048b .
publickey.qubit-ctf@protonmail.com.asc: PGP public key block

The message is encrypted with the provided public key, as we can see from the following Key IDs:

$ gpg --list-only message.txt.zip.gpg 
gpg: encrypted with RSA key, ID 0x00BE2158055B7BE3
$ gpg --with-fingerprint publickey.qubit-ctf@protonmail.com.asc 
pub  2048R/0xED6335A0793E46A6 2019-09-13 qubit-ctf@protonmail.com <qubit-ctf@protonmail.com>
      Key fingerprint = 554A 4E4D 9671 8A07 1A98  E228 ED63 35A0 793E 46A6
sub  2048R/0x00BE2158055B7BE3 2019-09-13

This public key seems to be the legit 2048 bit RSA public key, so we don’t need to try to crack it. Probably there is another way. The challenge is in the category Forensics, so we can try the forensics approach and examine the disk image. We can examine metadata of the files, metadata of the filesystem, the “empty” space, the slack space, strings scattered on the disk image… There are many things we can examine, but the “empty” space sounds reasonably right now. So, we can try to recover deleted files. Use tool of your choice, e.g open source program photorec disk.img:

Fig. 2: Photorec User Interface

PhotoRec 7.0, Data Recovery Utility, April 2015
Christophe GRENIER <grenier@cgsecurity.org>

Disk disk.img - 1024 KB / 1000 KiB (RO)
     Partition                  Start        End    Size in sectors
   P FAT12                    0   0  1     0  62 16       2000 [NO NAME]

1 files saved in ./recup_dir directory.
Recovery completed.

You are welcome to donate to support further development and encouragement

The recovered file is the ZIP file containing message.txt with the following content:

Hello, my friend.

Probably you are trying to find the next flag. So, here you are:


So, the last line is the Base64-encoded flag, all we need to do right now is only decoding it:

$ base64 -d
Bingo:  QCF{d5efea35ae004db6f876ca77f0366d59}


HashBreaker (20 pts., 5 Solves)

Is it even CTF without cracking the hashes? This time, we have one SHA256 for you.
Wait, is it hard to break SHA256? Maybe, but... follow the Rules, because its
sentences and words contain wisdom.
And also don't afraid of chains, because chaining can be more helpful than painful.

SHA256 to crack: a4c9f4214ee26e0d26d15d106326d92a371881dd1a98ddd1a810e2072459f853

Bruteforce for crack SHA256 is not good idea, so what now? Maybe good wordlist can help. But what is good wordlist in this case? The task contains small hints. It mentions the Rules and chains and chaining. It seems that we can use the Rules of this CTF and chaining (concatenating) the words from it. Let’s do this, grab all of the words from CTF Rules, make unique list of them (or set in Python) and create the dictionary contains single words and “chains” of double words and triple words. We get approx 8.5 mil items in our wordlist and it tooks only few seconds to crack the SHA256 hash and find the flag:

$ time python sha256-crack.py 

real	0m11.528s
user	0m11.203s
sys	0m0.321s
# sha256-crack.py

from hashlib import sha256
import sys

sha256hash = "a4c9f4214ee26e0d26d15d106326d92a371881dd1a98ddd1a810e2072459f853"
flag = "QCF{{{}}}"

with open("wordlist-rules.txt", 'r') as f:
	words = set(f.read().replace('\n',' ').split(' '))

wordlist = []
for w1 in words:
	for w2 in words:
		for w3 in words:

print len(wordlist) 

for w in wordlist:
	if sha256hash == sha256(flag.format(w)).hexdigest():
		print flag.format(w)

Long Text (30 pts., 11 Solves)

The task contains the long unreadable text, it seems that it is is encrypted with some basic cipher, probably like Caesar cipher. After first guess, it turns out that this is not the simple substitution cipher, we need to try something more advanced. Maybe poly-alphabetic substitution cipher, like Vigenere cipher. The text itself is long enought, so it should be possible to crack it using frequency analysis or index of coincidence. Or, we can save our time and work, and find the online tool for decrypting the Vigenere cipher.

Fig. 3: Vigenere Solver


Halloween (15 pts., 8 Solves)

This task came in the form of one picture only and the flag was hidden only in the content of the picture itself. No metadata, no encodings, no digital artifacts. This task could be printed on sheet of paper and the solution is the same.

Fig. 4: Halloween

What is unusual in this picture? Is there some pattern? Yes, it is. Graves. They are placed in groups of 1-4 graves separated with something or just with empty space. This points us to the Morse Code. The small graves are dots, the bigger ones are dashes. The flag is “FAST RED CAR”. Ferrari has also been accepted.

Houses (35 pts., 6 Solves)

Little bit of Stego, little bit of OSInt, but mainly Puzzle. And two images. The first with houses, the second with keyboard.

Fig. 5: Houses

Fig. 6: Keyboard

For now, the keyboard seems to be quite irrelevant. Probably more important is the first one. The houses could be the real, but… where are they, in which city? We can use the POI with Nexnet, a.s. and search for it. There are only few places with this company, and one with the brick house is in the Zlin, Czech Republic. After we zoom out, we will get overview of the neightbourhood. The houses on our picture are shown from their north side, so wi rotate the map and… voila… they resemble the keyboard. Similar keyboard as is in the second picture. So, the houses are keys on the keyboard. Now, we need to find each house on the map and substitute it with its key (char) as is shown on the following picture:

Fig. 7: Houses as keyboard

And the answer is “QCFZLINKBD” or “QCF{ZlinKbd}”.


MailMe (10 pts., 9 Solves)

Task was to find an email address related to this CTF and send a message with specific subject. There are couple of places where to search, but if you try the GPG Message challenge, you should get the right email address: qubit-ctf(at)protonmail(dot)com. That is all.

Traveler (40 pts., 11 Solves)

Federica was in London and probably she used her iPhone with WiFi turned on. We can try to find her using WiFi networks mapping databases like WiGLE. The search query like “iPhone”, “Federica” and even the regular expression “%iPhone%Federica%” returns too much results. On the other hand, if we prepare more specific query including the geolocation (GPS coordinates of the London), we can get only the one result, located near the crossroad of Downing Street, Richmond Terrace, Parliament Street and Whitehall.

Fig. 8: WiGLE search

Fig. 9: WiGLE map

Now use the another map and we will see also the name of the statue on the east: Montgomery.

Fig. 10: Montgomery


Jigsaw (20 pts., 17 Solves)

Fig. 11: Puzzle It is easy, isn’t it? Solve the Jigsaw puzzle and get the flag. If I tried it, it tooks me approx 20 minutes, even on laptop withou mouse. There are some approaches to speed-up this process. Quick “mixing” of puzzle pieces can help a little. Or… what do we want? To find the flag. And what is the flag? The text string “QCF{…}”. And where is it? Hmmm… Probably somewhere in the file (or in some temporary file). And also in the memory. But the straightforward solving the puzzle is also fun and it is recommended as a relax during long winter evenings.

Fig. 12: Puzzle

Arduino (30 pts., 5 Solves)

We are trying to find he secret flag which is encrypted in the hardware chip (in the Arduino firmware). When we launch Arduino with this firmware, it communicates over the Serial line and give us a prompt QuBit #Sofia2019 CTF>. We can try the “h” command (as help), and we will see the following output:

QuBit #Sofia2019 CTF> 
h	print this help
f	print encrypted flag
d	decrypt flag in memory

However, printing encrypted flag doesn’t seem to be useful, even if this flag is printed after command “d” for decrypting. Now, we have at least three ways how to solve this challenge:

  • reverse engineering the firmware and find how the flag is encrypted. We can use the Online Disassembler and find the functions main, setup, loop and decrypt_flag (or more precisely, _Z12decrypt_flagv). It looks nasty.

Fig. 13: Arduino disassembly

  • patch the firmware to print the decrypted flag instead of the encrypted one: reverse engineer the AVR assembly and change the argument of some “print” function. Then run on the real Arduino (or emulator)
  • run this firmware in Emulator with the ability to view the content of data memory, e. g Emulare. We need to locate the placeholder for decrypted flag (filled with “XXXXX” pattern), enter command to flag decrypting and copy-paste the decrypted flag from memory. After that, we get flag “QCF{ArduinoMemoryInvestigator}”. See picture below:

Fig. 14: Arduino emulator


I hope all the participants enjoyed this CTF and had a chance to learn something new. Looking forward for the next contest. Finally, one graph with some stats:

Fig. 15: CTF stats