We return to you this year for our third round of the HackMIT admissions puzzle! The purpose of the puzzle was to identify motivated, resourceful hackers who will enjoy at HackMIT and make cool things.
Stop reading here and try the puzzle at hackmit.org if you don’t want any spoilers!
Finding the Puzzle
This hint led readers to hackmit.org, where clicking and dragging the letters of the large HACK logo revealed smaller hidden letters.
When these were dragged into the correct places on the splash page, the URL of the puzzle command center was revealed!
This year’s command center had the same backend as last year’s, but with the aesthetic of uni.xkcd.com. Puzzlers, identified by their GitHub usernames, could submit solutions and find links to the next puzzles in the chain here. We could also record their guesses.
Factoring the Time / Geohashing
Before puzzlers got started on the more intricate puzzles, they were directed to “puzzle 0,” meant to introduce the XKCD theme, at time.haxkcd.com. Upon opening it they found a rather minimal webpage titled “Think Fast”, showing an alarm clock with location and date.
Puzzlers familiar with XKCD realized that this was exactly the necessary information for a geohash, as described in https://xkcd.com/426/. Indeed, geohashing the displayed date, its corresponding DOW opening, and the location yields a correct answer to the puzzle (puzzlers could also use http://carabiner.peeron.com/xkcd/map/map.html). However, we wanted the answer to be accessible without puzzlers knowing that specific XKCD, and that’s where the “time” component came in. The hover text on the alarm clock reads “Think Fast. It all adds up in the end,” and searching for “think fast XKCD” leads to https://xkcd.com/247/, a comic called “Factoring the time.” Realizing that the time on the alarm clock cycled between only 6 times as the page refreshed and factoring the 24-hour formats of these times (as shown in the last frame of the comic) reveals that each of the times is a product of two primes. Furthermore, all 6 primes share the same 6 prime factors. Then, the second part of the caption comes in, “it all adds up.” Adding these prime factors yielded 426, which would lead hackers back to geohashing (XKCD #426).
Although some puzzlers solved the first (or zeroth) puzzle without too many problems, it also proved to be a particularly frustrating for others, and we got a lot of useful feedback on how it could be improved. Mainly, entering a (lat, long) tuple as an answer in command center was somewhat unintuitive to some, and others second-guessed their instinct to geohash by the dominance of the alarm clock. Both of these were valid pieces of feedback that we’ll keep in mind, but all in all puzzle 0 provided a simple introductory gateway into a series of intensely interesting challenges!
For our second puzzle we wanted to honor one of our favorite XKCD comics. Given the nature of the comic we knew we wanted a CTF-like puzzle part that started with an injection attack.
Hackers were directed to xkcde.com, which looks like the website of an elementary school whose system was recently broken into. The description on the homepage claims that the school is currently in the process of rebuilding their site and that all students need to re-register.
Puzzlers found their way to the student registration page and when making a page were greeted with a message to ask an admin to activate their account — a dead end. However, by inspecting the network they saw that a login attempt makes a POST request to xkcde.com/student/login with username and password in the body. Sending a malformed request to this address (such as one without the username and password) returns back a helpful stack trace.
From this stack trace we learn that the server is running Ubuntu and Node. With a couple of more malformed requests we can get different stack traces in order to reveal more information (as we’ll show later).
From the homepage, hackers could also access the login screen for an admin panel. Any attempts to brute force the login by using common combinations of usernames/passwords did not work. Many hackers familiar with the Bobby Tables XKCD immediately attempted to do a login bypass via SQL injection but found themselves stuck. Even though they were on the right track, they were missing an important bit of information. Sending a malformed request to the admin login endpoint yields a different stack trace.
From this stack trace, it’s clear that the Node server is using Mongo as its database which explains why SQL injection attempts were not successful. Using this information it is safe to assume that the query on their server looks like this:
Where both username and password are provided by the user. Here we can exploit the lack of input sanitization to login, and craft a username and password such that at least one admin account will match. There are many payloads that would successfully bypass login here, including
for both username and password.
Once logged in as admin, hackers could see all of the students they had registered earlier as well as their seemingly hashed passwords. Many hackers then started registering more students to try to find a pattern with the way the passwords were “hashed”. This is where most hackers realized that a longer password would show a longer “hash” in the admin panel so it is unlikely that passwords were hashed.
Registering a student with a very long password and decoding the hex shown in the admin panel reveals part of the original password, except the first couple of characters which seem to be encrypted in some way. This method also reveals the password salt (“salty”) that is added to the end of the entered password before it is “encrypted”. With more and more students registered it becomes apparent that the answer lies somewhere in the way the password is encrypted. Further inspection of the homepage reveals that the “Fun math puzzles” link links to the crypto section of Khan Academy. Given that the same number of bits always come back encrypted, some guessed XOR encryption and tried to XOR the password in the admin panel with the password they entered. They were right—passwords were salted and XOR-encrypted using the puzzle solution as a key.
We wanted hackers to play around the site as if they were the only ones. To do this, we integrated with GitHub and maintained all states (registered users/passwords) tied to the logged-in GitHub user. We also used hackers’ GitHub usernames to generate unique solutions. Like in last year’s QR puzzle, we hashed their usernames (appended with a secret) and reduced the hashes into two indices that select two random nouns. From there we simply took the entered student passwords, added “salty” to them and XOR’d each hacker’s unique solution in.
The rest of the implementation was a bit tricky — we wanted to be authentic and expose a real vulnerability while making sure its exploitation didn’t damage us or our users. We took several steps to limit damage that could be caused by an unexpected use of our purposely vulnerable application. First, we hosted this puzzle part on its own domain and AWS box completely separate from any HackMIT infrastructure so that even in the worst case scenario damage would be minimal. Second, we ran all user queries against a dummy “Admin” collection and made sure to not return any results back to the user (other than a successful login in the case the query matches a user). Lastly, we placed a limit on the number of queries a hacker could run before being locked out of the application.
Together, hackers registered over 8000 students to XKCDE. Based on discussion in the puzzle Slack, hackers overall found this puzzle to be enjoyable.
Next, they faced the raptors…