How to get a job interview with the Norwegian Police Security Service

The Norwegian Police Security Service had a job posting with a "digital riddle" to find the right candidates for a job. Here's (hopefully) the solution.

Published: Mon, January 14, 2019, 06:45
Category:
Security
Tags:
Behind the news
Challenge

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. In December 2018 they posted a job listing seeking a "curious solution-oriented digital forensics specialist".

In the job listing they included a limerick which was a riddle that they wanted people to solve. I didn't hear of the job posting until it suddenly in January was on the front page of most Norwegian newspapers. The titles were typically something like "if you solve this puzzle the job could be yours".

The shark theme 🦈 🔗

Almost every part of the whole mystery had a shark theme. The background for that was a bit embarrassing episode from October 2018 where suddenly PST tweeted a picture of a shark. It was the 7-year-old child of one of the PST employees that had accidentally clicked the share button while playing the game Hungry Shark Evolution on his father's iPad. This of course sparked speculations of their Twitter account being hacked. (It was not an iPad with any classified information, but an iPad used for updating Twitter from home. (Their Twitter account is also closed for direct messages.))

Oh, and "hai" is the Norwegian word for "shark".

Step 1 - the limerick 🔗

The limerick in the job posting was as follows:
En oktobermorgen fikk vi pulsen til å øke
var det en hackeR som hadde lykkes med forsøkeT
men en HAI I en TWeeT
er ikke særlig 1337.
løser du gåtEn bør dU vurdere å søke

The direct meaning of it the limerick doesn't matter itself, but there's a pattern in it:
En oktobermorgen fikk vi pulsen til å øke
var det en hackeR som hadde lykkes med forsøkeT
men en HAI I en TWeeT
er ikke særlig 1337.
løser du gåtEn bør dU vurdere å søke

The upper case letters are ERTHAIITWTEU. As you might know, .eu is a top-level domain, and you might've noticed there's also one single period in the limerick. This makes it ERTHAIITWT.EU. If you're quicker than me (and Norwegian) you might already see that the first part can be re-ordered to TWITTERHAI (Twitter shark).

Detour 1 🔗

I didn't see the re-ordering opportunity, so I visited http://erthaiitwt.eu. That site shows a hangman saying that the order is incorrect.

Solution 1 🔗

The right solution for the first step was to visit http://twitterhai.eu.

Step 2 - the HTML page 🔗

http://twitterhai.eu shows an image of a shark and gives another poem telling you to look around. Now, I would always look at the source code, but I saw that there was this strange spacing in the middle of the word være. This is a sign that there's something going on with the HTML source code.

Do you see the odd line breaks and what the first column says? Shark.html

Detour 2a 🔗

I tend do look closer at robots.txt and have even made a nice robots.txt linkifier bookmarklet to easily visit and open links from exactly that file. Visiting http://twitterhai.eu/robots.txt you get a helpful hint saying Use the source, Luke!.

Detour 2b 🔗

I'm used to files being lower case so I went straight to http://twitterhai.eu/shark.html. There you get the helpful hint that Case matters. Watch your characters.

Solution 2 🔗

The solution for the second step was to visit http://twitterhai.eu/Shark.html.

Step 3 - the image 🔗

While I suppose some people stopped looking when they found http://twitterhai.eu/Shark.html which gives a tip about taking the time to write a good job application. However, there's a HTML comment telling that they have more puzzles if you look more closely.

I couldn't see any other clues or directions to go other than the image from step 2. What made this one hard for me was that the tools I used to look for Exif metadata didn't reveal anything. As I understand it the solution wasn't hiding in Exif at all, but rather a (JPEG) file comment. There are online tools out there that gives much more than just Exif, and if you're on a Unix-like system you could use a variant of the file command to get the info needed:

file 1337_shrk.jpg

1337_shrk.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16,
Exif Standard: [TIFF image data, big-endian, direntries=3, PhotometricIntepretation=RGB, orientation=upper-left],
comment: "/haitech_secure.html", baseline, precision 8, 851x514, frames 3

Solution 3 🔗

The solution for the second step was to visit http://twitterhai.eu/haitech_secure.html.

Step 4 - the JavaScript 🔗

http://twitterhai.eu/haitech_secure.html contained some general text with some "tips" for when applying for a job. More importantly it contained a password field and a login button.

The source code revealed a client side validation of the password by first verifying the password and then using the password as a key to decipher a ciphertext.

The JavaScript doing the actual verification of the key was as follows:

password.charCodeAt(0) == 8 * 8 + 8 && 
password.charCodeAt(1) == Math.pow(9, 2) - 29 && 
password.charCodeAt(2) == Math.pow(10, 2) + Math.pow(3, 2) && 
password.charCodeAt(3) == password.charCodeAt(2) && 
password.substring(4, 5) == 3 && 
password.charCodeAt(5) == 7 * 17 - 5 && 
password.charCodeAt(6) == password.charCodeAt(0) && 
password.charCodeAt(7) == password.charCodeAt(1) && 
password.charCodeAt(8) == 0x69

Obviously the password was 9 characters long and it was just a matter of calculating each char. I just copied and pasted a bit and used the following quick and dirty JavaScript in the console to print out the password and run the login function which gave an alert box with the next clue.

var password = [];
password[password.length] = 8 * 8 + 8;
password[password.length] = Math.pow(9, 2) - 29;
password[password.length] = Math.pow(10, 2) + Math.pow(3, 2);
password[password.length] = password[password.length - 1];
password[password.length] = '3'.charCodeAt(0);
password[password.length] = 7 * 17 - 5;
password[password.length] = password[0];
password[password.length] = password[1];
password[password.length] = 0x69
for (var i = 0; i < password.length; i++) {
    password[i] = String.fromCharCode(password[i]);
}
password = password.join('');
document.getElementById("password").value = password;
console.log(password);
login();
Solution 4 🔗

The password needed to proceed was H4mm3rH4i (hammerhead shark).

Step 5 - the Caesar cipher 🔗

The alert box outputted the text Caesar synes at du skal ta turen hit: uggc://gjvggreunv.grpu/unv_gurer.ugzy meaning Caesar thinks you should go here: uggc://gjvggreunv.grpu/unv_gurer.ugzy.

Just by looking at the last part itself it seemed pretty obvious that this was a Caesar cipher. This had to be http://somethingsomething.html. There are plenty of places to solve these kinds of code, but a quick JavaScript also does the trick:

var cipher = 'uggc://gjvggreunv.grpu/unv_gurer.ugzy';
var shift = cipher.charCodeAt(0) - 'h'.charCodeAt(); // Char we suspect to know
var charDistance = 'a'.charCodeAt();
var cleartext = '';
for (var i = 0; i < cipher.length; i++) {
    var charCode = cipher.charCodeAt(i) - charDistance;
    if (charCode >= 0 && charCode <= 25) { // a-z
        cleartext += String.fromCharCode((((charCode + shift) % 26) + charDistance));
    } else {
        cleartext += cipher[i];
    }
}
console.log(shift, charDistance, cleartext);
Solution 5 🔗

The plaintext for this one was http://twitterhai.tech/hai_there.html.

Step 6 - the ASCII art and secret folder 🔗

http://twitterhai.tech/hai_there.html just told that you should follow the Twitter user twitt3rhai (Twitter shark).

The latest tweet was the text "#justdoit, or make your ROBOTS do it. Transfer teXt to an ediTor". I suppose this was a double hint; another trip to robots.txt and transferring the rest of the tweets to a text editor.

The robots.txt pointed to the path /min_hemmelige_mappe/ ("my secret folder").

There were 65 other tweets containing shark and fish related words. It looked like some kind of cipher. The best thing to do was to just copy all the tweets into a text editor:

Tigerhai HvithaiHammerhaiHvalhai Oksehai Domenehai Brugde
Brugde DomenehaiTigerhaiHvithai Hvalhai Hammerhai Oksehai
HammerhaiJaws   Fish   Hvalhai Oksehai Domenehai Tigerhai
HvithaiHaiene   Tail   Tigerhai DomenehaiBrugde Hammerhai
HåbrannBrugde   Fins   HammerhaiBrugde HvithaiHvalhaiJaws
HvithaiHammer          Domenehai Tigerhai Oksehai Hvalhai
DomenehaiJaws   Mako   HåbrannHvithai HvalhaiTigerhaiMako
BrugdeOksehai   Apex   Tigerhai HvalhaiDomenehaiHammerhai
HvithaiBrugde   Jaws   HammerhaiOksehai BrugdeTigerhaiHai
Brugde HvalhaiHvithaiDomenehai Oksehai Tigerhai Hammerhai
TigerhaiHvithaiOksehai BrugdeHammerhaiHvalhaiDomenehaiHai
HvithaiHvalhai   BrugdeOksehaiDomenehai HammerhaiTigerhai
HvithaiSjøen   H   TigerhaiOksehai DomenehaiHvalhaiBrugde
Hammerhaien   Hai   Domenehai HvalhaiBrugdeHvithaiOksehai
HvithaiHai           DomenehaiHvalhai Hammerhai Oksehaien
HvithaiHai   Havet   Oksehai TigerhaiHvalhaiDomenehaiApex
OksehaiHai   Sjøen   HvalhaiBrugde HvithaiHammerhaiBrugde
BrugdeJaws   Finne   Brugde HvithaiHvalhaiTigerhai Haiene
HammerhaiDomenehaiBrugdeOksehaiTigerhai HvalhaiHvithaiHai
HvalhaiBrugdeTigerhaiHammerhaiHvithai Oksehai Domenehaien
Domenehaier           OksehaiHvithai HammerhaiHvalhai Hai
OksehaiTigerhai   HvalhaiDomenehaiHammerhai BrugdeHvithai
DomenehaiBrugde   TigerhaiHammerhai HvithaiHvalhaiOksehai
BrugdeHvithaien   HammerhaiDomenehaiHvalhai Tigerhai Mako
TigerhaiHvalhai   BrugdeDomenehaiHvithai OksehaiHammerhai
BrugdeOksehaien   HammerhaiHvalhaiDomenehai HvithaiBrugde
HvithaiJaws           HaiHvalhaiHammerhai BrugdeDomenehai
DomenehaiTigerhaiHammerhaiHvithaiBrugdeOksehai HvalhaiHai
TigerhaiHvithaiBrugdeHvalhaiOksehai Domenehai Hammerhaien
BrugdeTigerhaiHammerhai   DomenehaiHvalhai OksehaiHvithai
DomenehaiOksehaiSjøen     HammerhaiHvalhaiTigerhaiHåbrann
Hammerhai HvithaiBrugde   OksehaiHvalhai BrugdeTigerhaien
HvithaiBrugdeOksehaiHai   TigerhaiDomenehai HvalhaiBrugde
HvalhaiOksehaiDomenehai   TigerhaiBrugde HammerhaiHvithai
Tigerhai HvithaiOksehai   HammerhaiDomenehaiBrugdeHvalhai
HvithaiOksehaiBrugde         Hammerhai Tigerhai Domenehai
HvalhaiHammerhaiHvithaiBrugdeTigerhai OksehaiDomenehaiHai
DomenehaiHvithaiBrugdeTigerhaiHammerhai Hvalhai Oksehaien
OksehaiBrugdeBrugde         Hvithai DomenehaiTigerhaiApex
HvalhaiHvithaiJaws   Haier   DomenehaiHammerhaiTigerhaien
TigerhaiBrugdeOksehaiSjøen   Domenehai HvalhaiHammerhaien
DomenehaiHammerhaiHavet     BrugdeOksehai HvithaiTigerhai
HvalhaiHammerhaiHvithaiHai   Brugde Oksehaien Domenehaien
DomenehaiBrugdeHai   Havet   Hammerhai Hvalhai Tigerhaien
HvalhaiOksehaiBrugde        BrugdeDomenehaiTigerhaiBrugde
Hvithai DomenehaiBrugdeHammerhaiTigerhaiHvalhai Oksehaien
HvalhaiBrugdeHvithaiDomenehaiOksehai Tigerhai Hammerhaien
BrugdeHvithaiBrugde         HammerhaiTigerhaiHvalhaiSjøen
Domenehai Tigerhai   Sjøen   HvithaiHammerhai Brugde Jaws
OksehaiBrugdeHvalhaiHvitha   Domenehai Tigerhai Hammerhai
TigerhaiHammerhaiHavet     HvalhaiHvithai BrugdeDomenehai
TigerhaiDomenehaiHammerhai   Hvalhai HvithaiOksehaiBrugde
HvithaiDomenehaien   Finne   HammerhaiHvalhaiBrugdeBrugde
BrugdeOksehaiBrugden        Hammerhai Hvithai Domenehaien
HvithaiBrugde TigerhaiOksehaiDomenehaiHammerhai Hvalhaien
DomenehaiHammerhaiOksehaiHvithaiHvalhai Brugde Tigerhaien
HammerhaiTigerhai           DomenehaiHvithaiBrugdeHvalhai
HvalhaiBrugdeHvit   Haier   OksehaiTigerhai Domenehai Hai
OksehaiBrugdeHvithaiJaws   HavetDomenehai TigerhaiHvalhai
DomenehaiHvithaiHåbrann   Hammerhai Brugde OksehaiHvalhai
DomenehaiHvalhaiBrugde   OksehaiBrugdeHammerhai Hvithaien
DomenehaiTigerhaiApex   Hammerhai Hvithai Hvalhai Oksehai
OksehaiHammerhaiJaws   DomenehaiTigerhaiBrugdeHvalhaiJaws
Hvalhai HvithaiTigerhaiDomenehaiBrugdeHammerhai Oksehaien
Håbrann TigerhaiOksehaiHvithaiBrugdeHvalhaiHammerhaiHavet
Solution 6
There were two things to draw from this step. The first was the URL to http://twitterhai.tech/min_hemmelige_mappe/, and the second was the word HAI1337 (shark 1337) hiding in all the tweets.

Step 7 - the Wireshark dump 🔗

The mentioned URL http://twitterhai.tech/min_hemmelige_mappe/ was the URL to a directory containing a file called just haimat (shark food), and it was indeed shark food. Again the file command proved a quick and simple way of determining the file type:
file haimat
haimat: pcap-ng capture file - version 1.0

A pcap-ng capture file is a file with a packet capture format that contains a "dump" of data packets captured over a network - a file typically seen from the good old packet analyzer Wireshark.

Now, I'm no expert in Wireshark, but I have used it now and then to listen in on network traffic. I used it extensively while building the app for my HDL Buspro smart home - to see how the different components were talking together. Luckily this dump only contained 400+ packets.

I might very well have missed stuff in the dump, but I did find two things. The first was a web browser visiting the root of a server and getting back the following HTML:

<html>
<head>
    <title>Sharky Secret Distributor</title>
</head>
<body>
    Her er dataene dine. Passordet har du allerede... <a href="/secret_data.zip">secret_data.zip</a>
</body>
</html>

The page said Here's your data. You already have the password... and linked to ZIP file.

The second thing of interest was the response to the the request for the actual ZIP file. Wireshark lets you easily save files that been transferred over the wire.

Solution 7 🔗

The solution was to extract the ZIP file from the packet capture file.

Step 8 - the ZIP file 🔗

Trying to unzip the ZIP file it asks for the password for the file insignificant_shark.png.

Solution 8 🔗

As hinted, you were already supposed to have the password. Yes, the password was HAI1337.

Step 9 - runes and steganography 🔗

Of course the image was of a shark. The shark had what looked like runes on its side. Looking at a table of a runic alphabet the three runes can be transliterated to l s b.

What could the letters LSB mean in context of an image? Least significant bit. That matches the file name of insignificant_shark.png. Steganography is the practice of concealing a file, message, image, or video within another file, message, image, or video.

There are many online tools for looking for secret messages in images.

Detour 9 🔗

If you decoded the image incorrectly the image would reveal a QR code which was encoded with the helpful text You thought we would hide anything of SIGNIFICANCE? Not the LEAST....

Solution 9
Decoding the image looking at the LSB reveals the URL http://twitterhai.tech/u_are_th3_winrar.jpg.

Step 10 - Winrar 🔗

The image at http://twitterhai.tech/u_are_th3_winrar.jpg has the text "Do we we have a winner?".

The puzzle can't end with a question. What should we be looking for here? The URL says "winrar" and not "winner". The simple image is a stunning 9 MB. It is possible to hide files at the end of images. WinRAR is a file archiver utility for ZIP files and RAR files.

Solution 10 🔗

The solution was to e.g. use WinRAR to extract the files gratulerer.txt and gratulerer.gif from the "image".

We have a winner 🔗

I wouldn't be very surprised if there was another level of puzzles and solutions hidden here somewhere, but who knows. The file gratulerer.txt (congratulations.txt) contained a greeting telling that all the puzzles have been solved and included a (shark related, of course) code word that could be used as a proof of challenge completion. gratulerer.gif is GIF from the movie The Great Gatsby.

So does all this prove that you are ready for working as a digital forensics specialist for a national security agency? Of course not in itself. But I suppose it's a good starting baseline for applicants. Solving all the pieces shows a basic understanding of a wide area of topics like knowing a little bit of code, some basic cryptography, a bit networking and have some general smartness. Of course, if you applied on January 8th or later you might expect some extra questions in regards of the solution as someone solved the challenge on Reddit and there's also a write-up on GitHub. 😀 I wanted to wait to publish this until after the application deadline.

Giving a challenge like this also helps spread the word about the job opening, especially when it ends up on so many news paper front pages. I hope PST got some good candidates. :)

Get notified when there are new posts! :-)