On one fine morning of our final semester, we got an email asking us to fill some details for use in the graduation certificate. There was a black-and-white photo of us visible after logging into the portal. (I think we had uploaded it sometime back.) Forced by habit, I hovered over it to see the URL. It seemed hackable. I copied it to open in an incognito window to see if it would still work without authentication / cookies. It did! I changed the ID in the URL to confirm if I could see the photo of someone else as well. It was indeed accessible.
I stood up from my chair in the computer lab and looked around.
(Full disclosure: Okay, I didn’t! I was too damn lazy that way. I added that for dramatic effect! Real-world does not have such things. 😝)
One of my friends was sitting diagonally behind me, so I turned around and told him the images are open. He replied that he had noticed that as well. When will our college start investing in security?
I had a junior who was working hard to introduce the concept of cybersecurity to our administration. We used to syncup regularly on the progress. All his advice was falling on deaf ears. (The situation slowly improved a lot. He hacked - and demoed - a lot of systems in the coming years which led to acknowledgement of the vulnerabilities by them. I also got to know that he led many initiatives there and is now expanding it across the country.)
So back to the task at hand! Facemash was already running through my mind. Let’s think it through! What would I need? I wanted to be sure that it would work before investing time into it. Some people call me lazy, I prefer the term smart.
- If I start downloading all the images at once, my IP might get blocked. To combat it, I could just add a delay. There were less than 1000 students in the final year so even adding a 5 second delay would lead to downloading all of them in about an hour.
- What about logs? Probably, I should download them from a random PC in the computer center and not from my lab PC.
- To access internet in the lab, you need to login first. But all our network requests also contained our credentials in transit. By running Wireshark on the network, I could easily get credentials of anyone. (If I recall correctly, it’s called ARP spoofing / poisoning.)
- Let’s say nothing works. What then? I tried opening 5-10 links and saving the image manually. They got saved as expected. I could also write a Selenium script to do this task, in case fetching them from the terminal fails. Cool, no obstacles here then! (Worst case, I’ll download them all manually.)
- I’d need a server and database to host this. I had played around a lot with Heroku and AWS already so this was sorted. I also had some AWS credits from participating in a hackathon during my Amazon internship.
Everything was in place.
Let the Hacking Begin!
- I started searching templates of Facemash on Google. With the right keywords, I was able to find a self-hosted version in PHP/MySQL. It had less than 250 lines of code (I checked!), spread across 4-5 files. I went through it and it seemed fairly consistent with what I was expecting (with ELO ratings).
- Spun up an EC2 server and installed LAMP stack on it.
- Wrote a few lines in bash, a little wget magic is all it took to download all images within minutes.
- Uploaded all images and code to the server.
- Configured database connection in the code.
- Ran SQL queries to create two tables and insert images into the database.
- Took up a free domain and pointed it to the EC2 DNS.
- Within a few hours of the original thought, the MVP was up at
- Created a temporary email address and mailed the link to a few random people in our batch.
It spread like wildfire! By the next day, everyone in the computer lab was on it. I was on cloud nine, seeing 1000s of new database rows (read votes) every hour. I felt like I completed a sneaky heist!
The next day, someone started abusing it. The API to vote was vulnerable - it took two player IDs and who was voted to be hotter. People started writing scripts to send in numerous votes either in support of themselves or against someone else.
It was clearly visible on the website as well. It had sections showing the highest and lowest ranked players. The numbers were clearly rigged.
I brought the site down for maintenance immediately and deleted the spammy rows. I implemented a solution that passed a code, which was randomly-generated on visiting the homepage, along in the API call when someone clicked on vote. If the vote API was called w/o that code, it redirected to a page saying something along the lines of ‘scripts are not allowed’. I tested this and it looked good. The website was back up!
It again started getting spammed after a couple of days. It had become a cat-and-mouse game. Finally, I disallowed voting for a particular person. The system would then generate battles so you could not vote for / against any person altogether. You could only vote for the battle the system has generated for you. I was pretty satisfied with the solution and implemented it. The site was running again.
Eventually, like every other fad (2048, flappy bird, etc.), people lost interest in it and it died a slow death.
- SQL is powerful! All this happened with just two tables in place: images (with the id, file location, number of wins, number of losses, score as columns) and battles (with the id, winner, loser as columns).
Most of the business logic was also contained in the queries itself.
- Don’t reinvent the wheel. Initially, I was disappointed seeing that a lot of the required code was already available to use, but this is how development is in real-life as well. You mix-and-match things to create something of value.
- There was no feedback mechanism on the site. If people had an issue, they couldn’t report it.
- I could’ve have named it something better. Having
hotornot in the name implies rating, whereas it was more of a comparison thing.
- The API abuse led to people losing interest faster (similar to how I lost interest in Pokemon Go after people started using fake GPS apps!). If not for that, it could have been a longer fad.
To sum up, learn by doing! Don’t let the fear of failure stop you from trying something out. Going in, I knew that there were a lot of things that could go wrong! For example, I didn’t know how to design a decent page back then. If the code didn’t have the HTML / CSS code included, I’m pretty sure I would have done a crappy job at it. And it probably wouldn’t have taken off! Or I might not have the confidence to put it out in the open, then it would just have been an internal thing within our group. But you’ll never know unless you try! (You miss 100% of the shots you don’t take.) 👊
And yeah, this soundtrack does get you in the hacker mood! So put it on, and do epic shit. 😉
Until We Meet Again…