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:
- Easy
- Medium
- Hard
- ???
ClMystery
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
SEE INTERVIEW #904020
$ 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
SEE INTERVIEW #9620713
$ 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:
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!
Runes
Here you simply get an image of some Runes in a 5x5 grid pattern. Translating the runes to germanic you get:
A U T F H
N K R R U
I R E E R
M T E N R
T S A S N
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
k=2
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
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
k=4
By solving the other challenges we have more than enough shares to calculate k=4:
f4(1)=154315253502745748263921158136531
f4(2)=118249736918682056186291996969318
f4(3)=15906897834623111220488895351700
f4(4)=129795513036195528384758911437154
f4(5)=93387251992172469131037062226649
f4(6)=26931614658967185085992395585535
f4(7)=50678100992992927876293959379162
f4(8)=122616934121449585737032791184753
f4(9)=38479060342323683511721918291404
f4(10)=80773256441241836218608398852592
f4(13)=59372664790619416108628306171227
The answer here is: 3853947630400935826707330987989
k=9
By solving the other challenges we have more than enough shares to calculate k=9:
f9(1)=18431917384105746930902281228572
f9(2)=47116559448583257145160102856755
f9(3)=43359780976439286737053677319959
f9(4)=42692857761587209442928328545055
f9(5)=116094178794117191280811579355275
f9(6)=69710652888997871067650611403697
f9(7)=158227487577296337342281607135847
f9(8)=64858484496858151362905892937447
f9(9)=29731193030541008318265718603098
f9(10)=33908546822044766120109498310017
f9(13)=135438116597398552803261293518210
The answer here is: 100125717194428262877183837596008
Artwork
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
T
$ echo T| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
r
$ echo Tr| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
0
$ echo Tr0| npiet -t dbc6486d9c1788ccce2f4ece3e498fb3.png| grep stack | cut -d ':' -f 3 | grep -a -B1 underflow| perl -e "while (<>) {print chr }";echo
u
....
$ 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
.
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
Explosion
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.