CTF write-up: Lork edition

Ben0xA has outdone himself with his latest CTF challenge.

In a lead up to BSides Detroit, the website hosting the challenges( bsjtf.com) suddenly changed into a terminal prompt.

It asked if I wanted to play a game.

Yes….yes I do.

(If you want to play it yourself, it’s up at https://bsjtf.com/lork/  Don’t read ahead if you want to figure it out for yourself!)




The scenario is that a rogue agent has hacked our server and replaced it with a complex set of puzzles.  First, I had to start the game.  The obvious choice was “Global Thermonuclear War”, as it references WarGames.  However, being inquisitive, I tried every game that showed up at the “LIST GAMES” command.

I got nothing but trolling responses until entering the obvious choice.

Now the real game begins.

The game is titled “Lork” and it is a clone of the old text adventure Zork, which I have fond memories of playing as a kid.  In the starting room, there is only one way to go.

Going that way gets you eaten by a grue.  Unless you turn on your flashlight first.

Now we get our first challenge.  There’s a door locked by a keypad which we have to get through.  The only clue is a note in a closet saying “Mr. Fuzzing’s name must be fuzzed, trimmed, and truncated.”  After playing around with manipulating my entries to try bypassing the keypad, I took note of the fact that the server response was a block of JSON data followed by a zero.  I also noted that although I could enter up to 45 characters, the username returned was cut down to 20.

If you enter any random data, it says you must be ADMIN.  If you enter ADMIN, it says you are not ADMIN.  But, because of the operations listed in the clue (fuzzing, trimming, truncating), I figured out that entering ADMIN followed by 15 spaces and then 1 would let me through.  The spaces pad it out to the maximum length, but they are then trimmed.  The server then has the name ADMIN, but the extra 1 replaces that 0 in the server response.  That changes the admin flag from false to true, and we are on to the next room.

In this room, there is a blank piece of paper, but when a candle is lit with the provided matches, some glowing symbols appear.  The symbols are <~3<~>, <~2#~>, <~1&~>, and <~1B~>.  The number 85 is also on the page.  Also in the room, there is a four digit lock on a trap door under the carpet.

After a little thinking and research, I realized that the symbols were numbers encoded in ASCII85.  I found a decoder online and got 9,5,2, and 3.  I iterated through combinations on the lock until I succeeded with 3592.

Down into the next room.  This one gave me some trouble.  There was a central room with chambers to the North, East, South, and West.  Each of the four chambers had a touch screen and a button.  The central room had a red and a green button on the floor, and a piece of paper.  The paper had a phone number and code on it.

I had seen this phone number in a prior CTF challenge, it’s a voicemail service.  When the number and code were dialed, a series of tones played.  I knew it was an rtty transmission that I needed to decode.

However, between calling on my cell phone and recording to my laptop speaker I got a very degraded signal.  I tried many settings, but nothing seemed to work.  I thought that perhaps the rtty would decode to a ciphertext that I would have to decode with something else, but that went nowhere.  Finally, I asked some questions to the challenge author, who confirmed the message would result in cleartext.  That focused my attempts, and I was able to see parts of words with certain settings.  Using the minimodem program on a Linux virtual machine, I was able to alter the baud rate by small increments.  These small changes made different letters appear more clearly, and eventually, I was able to tease our parts of the message.  Most importantly, I clearly saw r7=FLOWER.  That let me know that the message had the codes for each of the four touch screens.  Through trial and error and some educated guessing, I got the four codes: CONTRA, FLOWER, NITRO, and FROGGER.  That first password also gave me an idea of what I had to do next.

The rooms were arranged like a Nintendo pad.  I pushed the buttons in the order of the famous Konami code: N, N, S, S, W, E, W, E

The green button in the middle then led to the final room (instead of a painful death, as it did every other time).

The final challenge presented a laptop logged into a bash prompt.  Most normal Linux commands resulted in “command not found”, but a few things worked.

First, I was able to list the current directory and see that there was a Python file.  Trying to run it resulted in a joke, claiming four pythons slithered out of the wall panels.  Thankfully, it did not kill you and make you start over.

I was able to see that contents of the python file with the ‘cat’ command.  The script would generate an encoded string based on three variables, the last variable would depend on the current time every 30 seconds.

The variables had been erased after the last time it was run (according to the history, which also showed the server to connect to when you have the correct password)

Based on the variable names and some quick Google searching, I discovered that the variables (firsthacker, rats, year) were based on Nevil Maskelyne, who famously interrupted Marconi’s demonstration of the telegraph in 1903.  The year was clearly meant to be 1903, and “RATS” was the initial uninvited message Maskelyne sent to Marconi’s telegraph.  The rats variable was mapped to the variable “ditdah” in the function, which indicated we needed to write it out in morse code (.-. .- – …) .

With the variable populated, the last thing to do is synchronize the time between the server and my machine where I could generate the password.  I hardcoded a time that was a little ahead of the reported time from running the ‘date’ command on the laptop.  The passwords I received had some characters which appeared to be erroneous or invalid.  I kept trying different things but (with some assistance from @Ben0xA) I realized that I had to just go ahead and enter those bad characters.  It worked!

This was a fun — occasionally infuriating — but ultimately satisfying challenge.