GCP CI/CD 01: Scanning GCP CI/CD's Private GitHub Repository — Writeup
- GitHub Enumeration 101 — full recon from a single PAT
- ▸ GCP CI/CD 01 — private repo to Cloud Run service name (this post)
Challenge Info
- Platform: CyberWarFare Labs (CWL)
- Category: CI/CD Security / GCP CI/CD
- Difficulty: Easy (10 points)
- Given: a GitHub Personal Access Token
- Goal: find the name of the Cloud Run service used to deploy this repo's artifact
Walkthrough
The challenge hands you a GitHub PAT, and the way in is a private repo. What we're after isn't a static secret — it's the target of a deployment action: the Cloud Run service name, which lives in the repo's CI/CD config file.
Step 1: Identity and repo enumeration
TOKEN="[REDACTED_PAT]"
curl -s -H "Authorization: Bearer $TOKEN" https://api.github.com/user | grep '"login"'
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.github.com/user/repos?per_page=100&visibility=all" | grep -E '"full_name"|"private"'
The owner is Secure-Corp-Pro, and the token can reach the private repo Secure-Corp-Pro/GCP-CI-CD-01.
Step 2: Clone it and take stock of the structure
When you need to find one specific setting inside a whole repo, cloning it and searching locally is by far the fastest route:
git clone https://[email protected]/Secure-Corp-Pro/GCP-CI-CD-01.git
cd GCP-CI-CD-01
find . -path ./.git -prune -o -type f -print
There's no .github/workflows/ anywhere in the tree, but the repo root does have a cloudbuild.yaml — and that alone is intel: this pipeline runs on GCP-native Cloud Build, not GitHub Actions.
Step 3: Read the Cloud Build config
cat cloudbuild.yaml
The deploy step (Deploy container image to Cloud Run):
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: ['run', 'deploy', '<SERVICE>', '--image', '$_DOCKER_URI/$_PROJECT_ID/$_ARTIFACT_REGISTRY_URI/$_DOCKER_IMAGE_NAME:latest', '--region', '$_DOCKER_REGION']
The first value right after gcloud run deploy is the Cloud Run service name (--image and --region are flags, not the name).
Flag (service name):
RedactedKey Takeaways
- "Deploying" is a CI/CD action, and the deployment target (cloud service name, project, region) lives in the repo's CI/CD config file — never in a data file. Going straight to the right file beats rummaging through the whole repo.
- "No
.github/workflows/but there is acloudbuild.yaml" is itself a finding: it tells you the pipeline runs on GCP Cloud Build. Both the presence and the flavour of a CI/CD config leak infrastructure details. - The first value after
gcloud run deployis the service name — don't confuse it with the--image/--regionflags that follow. cloudbuild.yamlusually leaks_PROJECT_ID,_ARTIFACT_REGISTRY_URI,_DOCKER_REGIONand friends at the same time — exactly the foothold intel you'll need for later GCP levels, so jot them down while you're in there.- This level is fundamentally reconnaissance (mapping the cloud environment), not the final attack. You're drawing the map, not kicking in the door.
Handy Tricks
# Pull Cloud Run deployment-related lines out of the repo
grep -rniE "cloud run|run deploy|deploy-cloudrun|service:" \
--include="*.yml" --include="*.yaml" .
# Cloud Build substitution variables start with $_ — the real values aren't in this file
# They usually hide in the Cloud Build trigger config, other files, or commit history
grep -rn '\$_' cloudbuild.yaml
Bonus: the "blueprint" this config file leaks
cloudbuild.yaml defines the full three-stage pipeline: build (docker packaging) → push (to Artifact Registry) → deploy (to Cloud Run), with the image path assembled from substitution variables like $_PROJECT_ID and $_ARTIFACT_REGISTRY_URI. So the shape of the pipeline is now known, but the actual values plugged into it haven't shown up yet — and that's precisely what GCP-CI-CD-02 goes digging for next.
Member discussion