[email protected]:~$

NIS Cybertalents CTF Brainteaser

The brainteaser part of the CTF is more disconnected from the rest of the tasks. These tasks are split into three levels:

  • Easy
  • Medium
  • Hard

These levels have varying number of sub-tasks:


This challenge is based on the open source Command Line Mystery. This is more of a linux shell task than a brain teaser.

We are presented with three clues from the start:

./crimescene:CLUE: Footage from an ATM security camera is blurry but shows that the perpetrator is a tall male, at least 6'.
./crimescene:CLUE: Found a wallet believed to belong to the killer: no ID, just loose change, and membership cards for AAA, Delta SkyMiles, the local library, and the Museum of Bash History. The cards are totally untraceable and have no name, for some reason.
./crimescene:CLUE: Questioned the barista at the local coffee shop. He said a woman left right before they heard the shots. The name on her latte was Annabel, she had blond spiky hair and a New Zealand accent.

Here it is practical to start with the last clue: Annabel. There is only two female Annabel’s that has been interviewed:

$ grep Annabel people 
Annabel Sun	F	26	Hart Place, line 40
Oluwasegun Annabel	M	37	Mattapan Street, line 173
Annabel Church	F	38	Buckingham Place, line 179
Annabel Fuglsang	M	40	Haley Street, line 176
$ grep -r Sun
interviews/interview-47246024:Ms. Sun has brown hair and is not from New Zealand.  Not the witness from the cafe.
$ grep -r Church
interviews/interview-699607:Interviewed Ms. Church at 2:04 pm.  Witness stated that she did not see anyone she could identify as the shooter, that she ran away as soon as the shots were fired.
$ cat interviews/interview-699607
Interviewed Ms. Church at 2:04 pm.  Witness stated that she did not see anyone she could identify as the shooter, that she ran away as soon as the shots were fired.

However, she reports seeing the car that fled the scene.  Describes it as a blue Honda, with a license plate that starts with "L337" and ends with "9"

Ok, so we have the car make, colour and parts of the license plate.

$ grep L337 -A5 vehicles  | grep -A4 Honda | grep -A3 Blue
Color: Blue
Owner: Erika Owens
Height: 6'5"
Weight: 220 lbs
Color: Blue
Owner: Aron Pilhofer
Height: 5'3"
Weight: 198 lbs
Color: Blue
Owner: Heather Billings
Height: 5'2"
Weight: 244 lbs
Color: Blue
Owner: Joe Germuska
Height: 6'2"
Weight: 164 lbs
Color: Blue
Owner: Victor Sidney
Height: 6'1"
Weight: 204 lbs
Color: Blue
Owner: Jacqui Maher
Height: 6'2"
Weight: 130 lbs

Now we have three males that are tall enough to still be a suspect:

  • Jacqui Maher
  • Victor Sidney
  • Joe Germuska

Lets check their memberships

$grep -E -r "Victor Sidney|Jacqui Maher|Joe Germuska" memberships/
memberships/Museum_of_Bash_History:Victor Sidney
memberships/Museum_of_Bash_History:Jacqui Maher
memberships/AAA:Joe Germuska
memberships/AAA:Victor Sidney
memberships/AAA:Jacqui Maher
memberships/Delta_SkyMiles:Jacqui Maher
memberships/Delta_SkyMiles:Victor Sidney
memberships/Terminal_City_Library:Jacqui Maher
memberships/Terminal_City_Library:Joe Germuska
memberships/Terminal_City_Library:Victor Sidney

Only Jacqui Maher and Victor Sidney are members of all the relevant organizations. We could submit both as flags, and see if one would be correct, but lets continue to narrow down our suspects.

$ grep "Jacqui Maher" people
Jacqui Maher	F	40	Andover Road, line 224
$ grep INTERVIEW streets/Andover_Road
$ cat interviews/interview-904020
Maher is not considered a suspect.  Video evidence confirms that she was away at a professional soccer game on the morning in question, even though it was a workday.

That leaves only Victor Sidney:

$ grep "Victor Sidney" people
Victor Sidney	M	34	Dunstable Road, line 28
$ grep INTERVIEW streets/Dunstable_Road
$ cat interviews/interview-9620713
Home appears to be empty, no answer at the door.

After questioning neighbors, appears that the occupant may have left for a trip recently.

Considered a suspect until proven otherwise, but would have to eliminate other suspects to confirm.
$ scoreboard Victor Sidney
Kategori: 3.1. Hjernetrim lett
Oppgave:  3.1.1_clmystery
Svar:     Victor Sidney

Gratulerer, korrekt svar!

Knock Knock

This challenge is simply a video of a Ken Barbie doll in a striped prison-like uniform. The Doll is placed behind bars and it is knocking on them in what is clearly a pattern.

There are several ways to solve this, but I opted for the manual one as it is likely fastest in this case.

I separated the audio track from the video with FFmpeg:

ffmpeg -i video.mp4 -vn video.wav

The I loaded up the audio in audacity to get a clear visual of the knocking pattertn: Knock-knock

The pattern used is something called Tap Code which has been, and probably is used by prisoners to communicate covertly. The code is quite simple where the listener only have to be able to separate groups of tapping series to discern the message being transmitted. The code is based on a 5x5 Polybius square:

  1 2 3 4 5
1 A B C/K D E
2 F G H I J
3 L M N O P
4 Q R S T U
5 V W X Y Z

So a H is 3+2 taps, an A i 1+1, an S is 3+4 etc.

Counting all the taps we get

... .... .... .. . .... . ..... .... ....   . .... .... ..... ... . . ..... .... .... . ..... .... ..  . ..... .... .... .... .... . ..... .... .. . ..... .... ..  .... .... . . ... ..... . .... . . ... ... . ... . .....

Solving this give you the string ORDETDULETERETTERERTAPDANCE – The word you are looking for is TAPDANCE:

$ scoreboard TAPDANCE
Kategori: 3.1. Hjernetrim lett
Oppgave:  3.1.2_knock-knock
Svar:     TAPDANCE

Gratulerer, korrekt svar!


Here you simply get an image of some Runes in a 5x5 grid pattern. Translating the runes to germanic you get:


Looking at the metadata of the file also show you that there is a comment added to the image:

$ exiftool runer/runer.png 
ExifTool Version Number         : 11.88
File Name                       : runer.png
Directory                       : runer
File Size                       : 1003 kB
File Modification Date/Time     : 0000:00:00 00:00:00
File Access Date/Time           : 0000:00:00 00:00:00
File Inode Change Date/Time     : 0000:00:00 00:00:00
File Permissions                : r--r--r--
File Type                       : PNG
File Type Extension             : png
MIME Type                       : image/png
Image Width                     : 800
Image Height                    : 600
Bit Depth                       : 8
Color Type                      : RGB with Alpha
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Background Color                : 0 0 0
Pixels Per Unit X               : 2835
Pixels Per Unit Y               : 2835
Pixel Units                     : meters
Comment                         : Columns
Image Size                      : 800x600
Megapixels                      : 0.48

This the 5x5 grid together with the Columns comment may lead us to the Columnar Transposition Cipher. I used dCode’s excellent implementation to solve this challenge.

With the permutation of 5,2,3,1,4 you will find that the the flag is: FUTHARKRUNERERINTERESSANT

Sharing Secrets

Wikipedia tells us that Secret sharing refers to methods for distributing a secret amongst a group of participants, each of whom is allocated a share of the secret. The secret can be reconstructed only when a sufficient number, of possibly different types, of shares are combined together; individual shares are of no use on their own.

In our case we get a little intro in the README, and some of the relevant keys to use.

The CTF presents the general formula as the following, where K is the number of shares needed to reconstruct the secret.

f_n(x) = a_0 + a_1*x + a_2*x^2 + a_3*x^3 + ... + a_(n-1)*x^(n-1)
f_n(0) = a_0 = ?

I did not want to do this by hand, and used a pre-made tool to do all computations. The only thing I had to do was to update the prime from k=3 and supply enough shares.

The share you need are found by solving other tasks, and running scoreboard --secret-shares.

Dine andeler:

2. Oppdrag
2.1_keystore              f4(1)=154315253502745748263921158136531   f9(1)=18431917384105746930902281228572
2.2_lootd                 f4(2)=118249736918682056186291996969318   f9(2)=47116559448583257145160102856755
2.3_loot_home             f4(3)=15906897834623111220488895351700    f9(3)=43359780976439286737053677319959
2.4_loot_vault            f4(4)=129795513036195528384758911437154   f9(4)=42692857761587209442928328545055
2.5_headquarters          f4(5)=93387251992172469131037062226649    f9(5)=116094178794117191280811579355275
2.6_decryption            f4(6)=26931614658967185085992395585535    f9(6)=69710652888997871067650611403697

3.1. Hjernetrim lett
3.1.1_clmystery           f4(7)=50678100992992927876293959379162    f9(7)=158227487577296337342281607135847
3.1.2_knock-knock         f4(8)=122616934121449585737032791184753   f9(8)=64858484496858151362905892937447
3.1.3_runer               f4(9)=38479060342323683511721918291404    f9(9)=29731193030541008318265718603098
3.1.4_sharing_secrets_k=3 f4(10)=80773256441241836218608398852592    f9(10)=33908546822044766120109498310017

3.2. Hjernetrim middels
3.2.1_artwork_del_2       f4(13)=59372664790619416108628306171227    f9(13)=135438116597398552803261293518210


By solving this we get a share for k=3

f2(x) = a_0 + a_1\*x
f2(2) = 29
f2(1) = 26
f2(0) = a_0 = ?

The answer here is: 23, and we get f3(5) = 38135776304496424228868822226466 as a hint for k=3


For k=3 we get some additional information that all the rest of the tasks are calculated with modulo of the elleventh prime: 162259276829213363391578010288127

f3(x) = a_0 + a_1*x + a_2*x^2
f3(2) = 73673086149599787963942979835811
f3(1) = 84657984464390529825364497916194
f3(0) = ?

Using 38135776304496424228868822226466 from k=2 together with the shares from the README we find that the answer is: 149298872572130536458843752197920


By solving the other challenges we have more than enough shares to calculate k=4:


The answer here is: 3853947630400935826707330987989


By solving the other challenges we have more than enough shares to calculate k=9:


The answer here is: 100125717194428262877183837596008


Artwork is the first of the medium brain teasers. In this challenge we get a picture named dbc6486d9c1788ccce2f4ece3e498fb3.png. The filename is the md5sum of the word esoteric, which is a great hint into what we are seeing here.


Another great hint is the sentence Intellect Confuses Intuition, a quote made by the famous artist and painter Piet Mondrian.

This leads us to the Esoteric programming language Piet. It works by interpreting changes in color in a picture, and supports several “opcodes”.

The program here is duplicated on the top and on the bottom of the image, so the image can be rotated 180 degrees and split in half horizontally without any problems.

I used perhaps the most prevalent Piet interpreter, npiet, to parse and execute the program.

\$ npiet dbc6486d9c1788ccce2f4ece3e498fb3.png

Part 1: HAVAL('mondrian')

Part 2: Enter password:

As can be seen above, there are two flags in this challenge. The first is a 3 round 128bit HAVAL hash of the word mondrian, the second is for now an unknown password.

Flag 1

I used this tool to generate the HAVAL hash: 153ceff44d69be87e33b1439c14899e8.

Flag 2

The second flag is a bit harder, as it asks the user to input a unknown password.

npiet is able to print trace debug information when running, this includes the contents of the stack. By converting the decimal output from npiet to ascii we can see all the output and input the program handles.

If we supply npiet with an empty password the password verification routine will encounter and print a stack underflow. It does this due to pushing our password on to the stack, and then pushing the first letter of the correct password on to the stack and subtracting our letter with the correct letter, checking to see if the sum is 0. If it is the letter is correct, if not it is wrong and the program will jump to the exit routine and print Incorrect password. By not entering a password the stack underflows, but we will be able to see which letter the routine tries to verify our input with:

$ echo | npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
$ echo T| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
$ echo Tr| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
$ echo Tr0| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
$ echo 'Tr0ub4d0r&3'| npiet dbc6486d9c1788ccce2f4ece3e498fb3.png

Part 1: HAVAL('mondrian')

Part 2: Enter password:
? ? ? ? ? ? ? ? ? ? ? ? correct horse battery staple

The password is Tr0ub4d0r&3, and the flag is correct horse battery staple.

To anyone who understands information theory and security and is in an infuriating argument with someone who does not (possibly involving mixed case), I sincerely apologize.

Another way could be to step through the progam with a debuger, for example PietCreator. This way you can NOP out all the checking instructions and just push the password on to the stack and read it out. Or easier just NOP through the whole part of the program until it prints the correct flag. Or even easier than NOPing out the verification parts, just remove everything other than the print of the flag:

$ convert dbc6486d9c1788ccce2f4ece3e498fb3.png  -crop %69x%100  split.png
$ npiet split-1.png
correct horse battery staple

Split 1


This task supplies an Object-Oriented binary which takes a number between 0 and 6 as input. It does a lot of recursion, object creation and math to output a number. This number is the flag.

The task is to find out what number it would have outputed for 6. The problem here is that for any number above 3 the program will crash or run forever.

For following inputs it gives the following outputs:

  • 0 -> 1 inc
  • 1 -> 4 add
  • 2 -> 11 mul
  • 3 -> 72 exp
  • 4 -> ?????
  • 5 -> ?????
  • 6 -> ?????

Hard ???

This folder is accessable only by root on the login-server, and by the time of writing I have not been able to gain access to this.