HackyEaster 2017 write-up

Easter 2017 – means new HackyEaster challenges are online. The challenges were easier than the ones on Hackvent 2016. For HackyEaster all challenges are released at once and it does not matter in what time-frame the challenges are solved, this makes the CTF much less stressful than Hackvent. I solved my last challenge on April 16th at 01:24 AM and completed the CTF after eleven others did before me. Here is a screenshot of the ranking at the time I finished the last challenge.

After the competition ended in total 53 hackers solved all challenges and got the full points.

01 – Puzzle this!

Author: PS
Level: easy
Solutions: 882

An easy one to start with.


You could actually play the game by clicking on the fields. If you were able to solve it the QR code was revealed. I started to play the game but in the end finalized the QR code with gimp, as I was faster this way. 🙂

02 – Lots of Dots

Author: PS
Level: easy
Solutions: 647

The dots in the following image contain a secret message. Can you find it?

(click to enlarge)


While examining the picture in Gimp I recognized that the orange color has slight different specifications. The bigger dots are RGB 232/178/97 and the small ones RGB 232/178/98! To solve this challenge I selected one of the colors with the pipette and filled the background with it. Then I used the “fuzzy select tool” to select a region based on the color. I just clicked somewhere inside the picture and the code was revealed: 70 57 49 36 13 22 8 42

03 – Favorite Letters

Author: Goo9ping
Level: easy
Solutions: 802

Francesca’s favourite letter is s
Riley’s favourite letter is o
Ellie’s favourite letter is a
Vince’s favourite letter is p
Quintain’s favourite letter is r
Otto’s favourite letter is i
David’s favourite letter is p
Tom’s favourite letter is l
Paul’s favourite letter is e
Ulrich’s favourite letter is y
Henry’s favourite letter is w
Norman’s favourite letter is h
Louis’ favourite letter is i
Zane’s favourite letter is s
York’s favourite letter is c
Bob’s favourite letter is h
Meave’s favourite letter is s
Ian’s favourite letter is o
Sidney’s favourite letter is g
George’s favourite letter is s
Kitty’s favourite letter is d
Wilbert’s favourite letter is h
Adam’s favourite letter is t
Xander’s favourite letter is i
Callum’s favourite letter is e
Jack’s favourite letter is r


This challenge can be solved with bash in 1 line:

04 – Cool Car (mobile)

Author: PS
Level: easy
Solutions: 481


I downloaded and decompiled the APK. The sensors are somehow used to change the graph in the mobile app. While browsing through the source code files I found interesting code-parts in two different files:


This means ‘k’ is the key to decrypt the scrambled egg, and ‘k’ is nothing else than the sha1 sum of the string “file:///android_asset/www/index.html”. I rebuilt the java-script function which is used to decrypt the scrambled egg and got the QR code.

This html page then reveals the QR code:

05 – Key Strokes

Author: PS
Level: easy
Solutions: 532


This one took me some time until I found out what to do with it. I first thought it’s a log from a keylogger. After thinking about where this could make sense, I finally figured out it is from the editor VI! After typing it exactly the way described I got the password: magicwandfrankfoxy.

06 – Message to Ken

Author: PS
Level: easy
Solutions: 460

Barbie has written a secret message for her sweetheart Ken. Can you decrypt it?



I had no clue what to do here. After googling for “barby encryption” I came across this interesting link: Barbie typewriter encoding! It even has an encoder on the website which works. The decoded string is:

Beloved Ken. The secret password is lipglosspartycocktail. Barbie xx

07 – Crypto for Rookies

Author: PS
Level: easy
Solutions: 458

This crypto is not hard to crack.


– B O N T B B O K –> http://www.dcode.fr/dancing-men-cipher
– B O N T E A O K –> Base64 encoded
– B O N T E B R K –> Index of the alphabet
– B A N T E B O K –> Rot13
– C O N T E B O K –> http://www.pruzkumnik.cz/praxe/sifry/tabulky.html
– B O N T E B O A –> Reverse string
– B O P T E B O K –> Caesar (rot 3)
– B O N Y E B O K –> Character codes

After having decrypted all words we need to get the final password. If we keep the format exactly as in the picture and look at the columns and rows we see that in each column one character is different than the others. If we take all different characters from left to right we get the final password: CAPYBARA

08 – Snd Mny (mobile)

Author: PS
Level: easy
Solutions: 330


Not much information here. I again worked with the decompiled APK and went through the code. In one java class I found what was needed to solve this challenge.


We need to send an android action.SEND intent as PLAIN_TEXT_TYPE containing a text which matches the sha1 hash “c95259de1fd719814daef8f1dc4bd64f9d885ff0”. Cracking the sha1 hash was easy as no salt was used. The needed text is “money”.

We can send Android intents from the command line with ADB:

I solved this challenge with the following two commands:

I over-engineered the solution for this challenge a bit, as it would have been possible to just share the text “money” with the app in Android to solve it. 🙂

09 – Microscope (mobile)

Author: PS
Level: easy
Solutions: 414


Another mobile challenge, again I worked with the decompiled APK.


The URL gets changed because there is “.replace(‘6’, ‘5’)” in the code. The QR Code is embedded in the website https://hackyeaster.hacking-lab.com/hackyeaster/challenge09_su5z47IoTT7.html and if we look at the HTML source code we can see the image is loaded from https://hackyeaster.hacking-lab.com/hackyeaster/images/challenge/egg09_fs0sYle2SN.png.

10 – An egg or not …

Author: inik
Level: medium
Solutions: 233

… an egg, that’s the question!

Are you able to answer this question and find the (real) egg?


Analyzing the SVG shows that there are duplicate coordinate declarations! In SVGs the last of the duplicated coordinates will be used, as it just overwrites existing locations with the new declarations. To solve this challenge, I wrote a python script which ignores duplicates if there is already a declaration for the coordinates.

Finally the solution looks like this:

11 – Tweaked Tweet (mobile)

Author: PS
Level: medium
Solutions: 108


This was the last mobile challenge. The only useful part I extracted from the APK was:

This one almost drove my crazy!

I tried to find any suspicious pattern, like to identify standard ASCII characters and extended ASCII characters, mapping them to 0s and 1s, exclude all extended ones, exclude all standard ones, etc. In the end I was identifying characters which were used as some Unicode combinations instead of the standard, most simple way. But I did not come to any solution.. After wasting hours on this one I just googled for “Twitter steganography”. First link http://holloway.co.nz/steg/ hosts a converter which can be used to decode our message!!!

If we enter our decoded string “#HackyΕaster
ⅰs a lot οf fun!
#сtf #haϲking-lab” into the decoder on the website, we get the result: st3g4isfunyo.

Stego is no fun yo 🙁

12 – Once Upon a File

Author: inik
Level: medium
Solutions: 252

Once upon a file there was a hidden egg. It’s still waiting to be saved by a noble prince or princess.


‘binwalk’ is a tool to identify header information within a file. If multiple files are hidden in one single file, ‘binwalk’ can identify and automatically extract these files. With ‘binwalk’ this challenge is pretty easy to solve.

The QR code is in the file ‘egg12.png’.

13 – Lost the Thread

Author: CoderKiwi
Level: medium
Solutions: 126

Searching for eggs is fun! But sometimes they come in weird shapes and sizes. Download the image and wind up the strand!


If we open the png with Gimp we can identify a pattern with two different shapes.

On first sight it looks like Morse-Code, but as there are only two different shapes it must be bits.

I wrote a python script which reads the pixels of the image. If a line is complete without interruption it is a 1. If the line is interrupted at the beginning by a transparent pixel it is a 0.

The result string looks like it contains ASCII art. I replace all the ‘0’ with ‘.’ and all the ‘1’ with Unicode blocks ‘█’. If we play a bit with the editor, resize the window, we get the QR.

We scan the QR code we get the password ‘kiwisarekewl‘.

14 – Shards

Author: PS
Level: medium
Solutions: 252

Oh no! What a mess!


We unzip the file and get 1600 files.

After trying out different ways of sorting I found the right way to do it:

I wrote a script in Python which sorts all the images the right way, creates a new image and combines all the shards in the right way to get the final image.


15 – P Cap

Author: PS
Level: medium
Solutions: 181

What about a little P cap?


I started analyzing the file with Wireshark. I found various interesting things inside the PCAPNG file. I landed on a suspicious polish forum but the traffic was encrypted and I didn’t find a key to decrypt the traffic. Then I analyzed the DNS queries and found a radio streaming service, but this was a dead end as well.

Finally I focussed on the SMB traffic. I used the function “Follow TCP” stream in Wireshark, selected only the incoming traffic and raw format. This way I could save the incoming SMB traffic to a file. From now on I could work with my favorite forensic tool ‘binwalk’. 🙂

A file called “imnothere.txt” is really suspicious! Again, using ‘binwalk’ on it shows the txt file is a JPEG image and not a text file.

I simply rename the file to imnothere.jpg and this is the result:

Now comes the confusing part! I tried to find anything related to this php file inside the PCAP file but didn’t succeed. It was a dead end and I tried to find other things inside the PCAP, but didn’t manage to find any… I stopped working on this challenge for some days and then tried again. I came to the conclusion that the really suspicious file imnothere.txt must be something. And finally tried to use this php path on the hackyeaster site:


This page reveals the needed QR code!

I didn’t like this challenge at all, because the end of the challenge was really irritating. Having a PCAP file and finding a path to a PHP file somehow leads to the conclusion that there must be more inside the PCAP file. It was really far fetched to try the path on the main HackyEaster website. I wasted way too much time on this one.

16 – Pathfinder

Author: MaMe82
Level: medium
Solutions: 181

Can you find the right path?


This challenge was a really nice one! Somehow the description of the challenge leads to the conclusion to connect to the server with netcat or telnet. But this does not return any response. Using nmap on the port 9999 reveals that it’s running an ‘abyss’ webserver. We can use ‘curl’ to connect to it.

No matter what I tried, the webserver always returned the same response. After trying to send different things to webserver I tried to change the UserAgent to ‘PathFinder’ and it worked!

It looks like we have to call all the possible path combinations. This calls for a recursive solution! My python script to solve this challenge looks as follows:

It turns out we have to bruteforce a Sudoku game. Nice! 🙂

The link https://hackyeaster.hacking-lab.com/hackyeaster/images/challenge/egg16_UYgXzJqpfc.png reveals the QR code.

17 – Monster Party

Author: otaku
Level: medium
Solutions: 75

The monsters do have a big party, jumping around like fools.

Each of them has its own jump-pattern. When two or more meet on a field, they are happy to see each other, but continue hopping. Passing the border on either side makes them appear again on the opposite side.

Make the monsters jump, and they will reveal you a secret!


This challenge looked like there would be a lot of coding effort to solve it. But fortunately looking at the source code reveals, that the board was created by using Javascript. Many parts can be reused.

I implemented a jump button to simulate the jumps of the monsters. I also added a second table where I colorize all fields with at least one monster black. But somehow it never revealed a QR code. Apparently it wasn’t as straight forward as I first thought. After reading the challenge description again I noticed that there is no information about the starting conditions, it’s not mentioned if the monsters already did a jump or not. What means the first jump the monsters do could be another one as I implemented. I added an offset of 1 and then the QR code was revealed after 72 jumps!

My implementation can be found here.

18 – Nitwit’s Doormat Key

Author: CoderKiwi
Level: medium
Solutions: 267

Being sure that no one can read the obfuscated code, bunny Nitwit has hidden the egg behind his login-page.

Find out the username and password to show that he lives up to his own name!


We can actually debug this. I first saved the page locally and added the ‘debugger’ keyword to the end of the script. Then I opened the page with ‘firedebug’ and set a breakpoint at the end of the script where the ‘debugger’ keyword is.

The Javascript code is heavily obfuscated and encrypted, but as Javascript runs on the client side, the final source which is executed must be revealed before execution. My breakpoint in ‘firedebug’ revealed this:

Finding out the username was much harder than the password. But with some manual work I eventually got it:

Getting the password was much easier, as we could just run the magic function with the username! The password is cvoozYs4ut5n. The egg with the QR code is then downloaded from this URL https://hackyeaster.hacking-lab.com/hackyeaster/files/bunnyXm4st3rcvoozYs4ut5n.txt.

19 – Disco Time

Author: DeathsPirate
Level: hard
Solutions: 139

Disco time!


This is the first challenge rated as hard.

First step with gifs is always to look at the single frames. The gifs with the cats didn’t reveal anything interesting. But disco2.gif did.

If we look at the frames folder, we can see a lot of red and white images. Looks like a pattern. We have 31 pictures before the color changes, this seems important.

I tried to combine the frames to a new picture with ‘montage’. ‘montage’ takes the pictures by name and orders them from top left corner to the top right corner, then it goes to the next line and so on.

I used montage this way:

This takes all the pictures from the frames folder and combines it into result.png. Result.png is 48×48 pixels and the boarders between the frames are 1 pixel. It takes 31 pictures per row and then goes to the next row. I had to do some trial and error to find the right values.

After rotating the picture and flipping it vertically I got this picture: 

It’s a bit hard to read, but the codeword is “PixelPixiesArePractical“.

Helpful Links:

20 – Spaghetti Hash

Author: PS
Level: hard
Solutions: 162

Lazy Larry needs to improve the security of his password hashing implementation. He decides to use SHA-512 as a new hashing algorithm in order to be super secure. Unfortunately, the database column for the hash can only hold 128 bit. As Bob is too lazy to extend the column and all the code related to it, he decides to shrink the output of the SHA-512 operation, to 128 bit. For this purpose he picks certain characters from the SHA-512 output for producing the new value.

You got hold of four password hashes, calculated with Bob’s new implementation. Can you find the corresponding passwords?

Lucky you, you know that the following web service is calculating Bob’s algorithm. However, the web service only accepts strings of length 4 or less – brute-forcing a password list thus is no option, since the passwords you are looking for are all longer.


The hardest part of this was to find out how the hash was shortened. I wrote a python script to solve this challenge.

First I use the webservice on hackyeaster.hacking-lab.com to find out which elements of the sha512 hash were taken into the shortened hash. To accomplish this i generate random 4-letter strings, calculate the sha512 hash and get the shortened hash from the webservice. I take the first element from the shortened hash and get the indices of all the matching elements in the sha512 hash. I repeat this with the next hash and only keep the indices which were there before – until I only have 1 left. Afterwards I move to the next element and repeat. This way I get get all exact positions which are used from the sha512 hash.

The second step was to bruteforce the passwords. Luckily no salt was used to hash the passwords, so I downloaded a wordlist with the top passwords and used it to bruteforce. I calculate the sha512 hashes of the passwords and whenever all elements of the shortened hash match with the positions in the sha512 hash I have a password.

Here is the full python script:

And this is how it looks like when executing the script:

The passwords are ‘Prodigy‘, ‘Cleveland‘, ‘benchmark‘ and ‘12345678‘.

21 – MonKey

Author: PS
Level: hard
Solutions: 74

The monkey is laughing at you. Get the hidden egg from his binary.


This challenge was the hardest one for me.

First step was to rename the ipa file to zip and extract the content. There are a lot of interesting files but no QR code in sight. Running ‘strings’ on the Monkey binary reveals some information. We can see that the library CCCrypt is used, there are function named aesDecrypt and aesEncrypt, we can see an encrypted string which probably is our encrypted QR code. And then there are these two strings “thisIStheKEYyoyo” and “monkeyluv$Banana”. I was a bit disappointed at the first moment, I thought this was too easy! But I was wrong, the 2 strings didn’t work as keys no matter how I tried. It is time to use a disassembler. I used hopper to solve this task.

Most interesting function is onBtnPressed. I worked mostly with the generated pseudo code of hopper, which worked pretty well:

We can see in the else-part at the end of the function, the two strings “thisIStheKEYyoyo” and “monkeyluv$Banana” are used in a log output to display the nopeCat! Nice play PS, nice play! 😉

Proceeding with the reverse engineering I found this method call: r4 = [[NSString stringWithFormat:@”%@omo%@”, @”makybk”, @”oaenklo”] retain]; This method results in the string “makybkomooaenklo”. But that string does not work as key either.

So, I stepped backwards from where the key actually was used:

  • aesDecrypt, the key used is r5
  • r5 is r6 UTF8 decoded
  • r5 is equal r4, r4 is “makybkomooaenklo”
  • As r5 was assigned from r6 before, we have to follow r6
  • r6 was last changed in the function sub_a75c()
  • input to sub_a75c is the key entered in the app, output is r6

We have to look closer what exactly happens in the function sub_a75c()

If we simplify this method to something more readable and only take the needed values from the array ’27fbc’, we get this function:

We have a password with the length of 16 characters. In this method the order of the characters of our password is chosen and a new string resulting in ‘makybkomooaenklo’ is created. ‘int original_password’ is a pointer to the address of the first element/character of the password used in the app and to it an offset from the array ’27fbc’ is added. All values inside ’27fbc’ are smaller than 0x10. Means that the ordering of the entered password is changed inside this function. In the app someone enters a password, this function changes the order of the characters and the result of it is the known string ‘makybkomooaenklo’. But the first typed password is used to decrypt the egg.

  • End ‘result’ is ‘makybkomooaenklo’
  • result[0] is address_of_first_character_of_our_password + 27fbc[0] (Which is 0x07)
  • result[0] is the character which is at position 0x07 of our password

We don’t know the entered key, but we know what it becomes after the function ‘sub_a75c’. Now we can reverse the function and get the key to decrypt the QR code!

To reverse the string I loop over the lenght of ‘makybkomooaenklo’ and for each position (0..15) we check at what index in ‘sub_a75c’ this number is located. When we found the position, we know the position of the character in the ‘makybkomooaenklo’ string.

Running the function reveals the password ‘koolokambamonkey‘. With this key we can decrypt the encrypted image of the QR code.

22 – Game, Set and Hash

Author: PS
Level: hard
Solutions: 226

Can you beat the tennis master?


This one was pretty straight forward. You connect to the server, the server gives you a sha1 hash and you have to decrypt it. If you manage to do so in the given time it’s a point for you otherwise for the server. The points are counted the same way as a Tennis match is counted. The game is started by entering “y”.

I first tried to solve it the same way as I solved PathFinder, with dictionary bruteforce. But apparently there is some logic behind, whenever the server is losing he uses stronger,combined passwords which are not in my wordlists and wins the game. Using this method the server always won 7-6,7-6,7-6. 😀

I solved it by using an API to crack the password hashes. I registered a free account on http://md5decrypt.net. This service was able to crack all password hashes and so I won the game. I think there is a more elegant solution to somehow trick the servers logic and win the game. But as I already had a working solution I was too lazy to look for another one. 😉

My python script:

Here is the output of running the script:

The password needed to get the points is “!stan-the_marth0n$m4n“.

23 – Lovely Vase

Author: PS
Level: hard
Solutions: 83

What a nice vase! Beautiful, don’t you think?


The image of the vase gave some hints how to get the passwords from the 3 strings. To solve this one you must know about Transposition Ciphers and Rail-Fence Ciphers. More information can be found on https://en.wikipedia.org/wiki/Transposition_cipher.


The top part of the vase reveals how to arrange the string of the first text and how to read it. It looks like a square. So I aligned the first string as a square 5×5.

We read the text the same way as the pattern shows on the vase and we start in the top left corner. It’s a bit tricky in the middle, but in the end the solution for the first string is: “the first part is adriane rick“.


The second pattern on the vase clearly shows a Rail-Fence cipher. I arranged the string this way:

Now again we start reading in the top left corner but follow the zig-zag stream. We get the sentence “the second part is susanna bob“.


For the last part the vase doesn’t help much. I could not read a pattern from the image. So I just aligned it like the first one 5×5. And because of the first two solutions I knew the sentence would start wiht “the third part is”. This made it a lot easier.

This time we start reading on the bottom left corner upwards. As soon as we reach the top, we continue on the second column upwards again. Solution of this one is: “the third part isclaire frank“.

Combine all the three names and we get the final password:


24 – Your Passport, please

Author: inik
Level: hard
Solutions: 93

After another exhausting Easter, Thumper decides to travel abroad for recreation. As a real h4x0r, he of course is using his own, homemade e-passport:

Write a client which connects to the virtual terminal, and fetch the portrait photo stored on Thumper’s passport! The virtual terminal is running on:

As a starting point for your client, the following eclipse project is provided:


On first sight this challenge looks pretty hard. I never heard about the jmrtd library nor anything about how to read out ePassports. But I know Java and with a bit of googling I was able to solve this challenge pretty fast.

Most information needed to get the image with JMRTD can be found in the documentation:

It was necessary to change localhost to the hackyeaster server in HE17Terminal.java. And the rest was all done in the Java class JMRTDMain.java.

Fist thing to do is to call the doBAC() function. This is used to do the basic access control. Normally you would have to do some authentication and provide a key for it. But in our implementation this is not necessary – we create a BACKeySpec object with the details of the passport to readout.

The passport image is saved in the DG2File. I’ve found this information in the documentations mentioned before:


File identifier for data group 2. Data group 2 contains face image data.
See Also:
Constant Field Values

From the DG2File we can read out the face information with the function getFaceInfos() and from there we get the image with the function getImageInputStream().

Here is my implementation of the JMRTDMain class:

Running this Java program saves the image as result.png in the running folder.

Leave a Reply

Your email address will not be published. Required fields are marked *