The apartment building where I live, like many other places, has introduced safety measures around COVID-19. They’re mandated by the government anyway.
One measure is to limit access to “amenity spaces” such as the gym, lounge, etc.
Some industrious company put out a new face on an old parking app to now be Amenity Pass. It’s what my landlord company uses.
Initially, after months of no gym time allowed in the building, only one household was allowed in at a time. There was hyper-competition around those reservations.
It was then that I wanted to write a “sniper” program for Amenity Pass. Like the OG eBay programs.
What’s the first thing you do before writing any bot, though?
That’s right – see if someone else already did and you can steal it.
If you search “amenitypass.app” across all of GitHub you’ll encountered this repo. Just as we’d hoped, it is indeed a working bot.
Let’s pause now for an explanation of Amenity Pass security measures.
- An admin for your building sets up an account for each apartment.
- Username is effectively your apartment number (i.e.
- You get assigned an immutable 6-digit passcode as a security measure for making or deleting reservations.
- Almost certainly you can bruteforce this but I did not go there. 🤐
- When you make a reservation, you also provide your full name, email address, and phone number.
- Though none of that seems to ever be validated in my experience.
I’d inspected traffic generated by using the web app. Retrieving available passes, making a reservation, all the good stuff.
There were some ideas in my head on how to write this program. Good ideas, I swear!
The guy whose bot we’re looking at took a much hackier, shorter approach than that. It is the reason we’re here.
Let’s take an innocent walk through his Node program. We’ll start in the
package.json file. What could possibly go wrong there?
Vulnerable dependencies?! Who cares.
Oh. Ah. Ehhhh. We already knew his name but now we have
App to Book Gym Slots on Behalf of Ebin Joby of Apt XX4 at XXXXXXXXe Apartments.
Exactly where he lives. Easy to search –
We proceed to
index.js with some curiosity as to why
nodemailer was present in the package file.
Boom! Maybe the post title spoiled it but –
There’s just a set of Gmail credentials hard-coded in there. I would never violate Google terms and conditions in any way, but through an act of magic, these creds revealed themselves to be valid.
What most interested me is that this must be an old account. My understanding is you can’t just mass-create Gmail boxes anymore for throwaway purposes, as you need a phone number for activation.
“Maybe this is their main Gmail account?” you ask.
I know it’s not because there’s a different Gmail for the author further down. Then
gymbot.js is a fork of this script and has an email for their roommate too.
Do we even care about the passcode and phone number at this point? They’re here anyway.
“What does this guy do for a living?!” you scream into the heavens.
LinkedIn reveals he’s a data scientist who, for God-knows-what-reason, wrote “I like to eliminate vulnerabilities” in his profile.
Uhhhh cool. At this point I did report the leak via GitHub issue. Who knows what will come of it.
Anyway – finders keepers if you get to that Gmail account quick 😉