Home

Welcome to RatKeeper

RatKeeper is Rat Corp’s internal configuration & secrets portal — it stores service credentials, API keys, and deploy config for the platform team. This marketing shell is the only public surface… in theory.

CWAP Module 08 · Hidden Credentials & Secret Disclosure · skill focus: find the leaked secret, then prove it by using it.

The build pipeline shipped more than the developers meant to. Somewhere in this app are hardcoded credentials, tokens, and keys — in the client code, in leftover files, in error output, in an exposed repository. Your job: recover them, work out what each unlocks, and use one to reach something you should not be able to reach. Start with the playbook below.

Secrets Hunting Playbook — Hidden Credentials & Disclosure

This panel teaches the technique. It intentionally does not list this lab’s hidden paths or secrets — recovering them is the exercise. Route everything through Burp and grep responses for high-entropy strings.

Where secrets hide

Credentials rarely sit behind a login — they leak through artifacts the build shipped by accident: client-side JavaScript (hardcoded API keys, config objects) and its sourcemap; an exposed .git directory (and secrets still in its history long after someone “removed” them); .env files and .bak/.old config backups; debug / verbose error pages that dump stack traces and connection strings; framework actuator/health/env endpoints; OpenAPI/Swagger specs with example keys; and browsable backup directories or downloadable archives.

The secret → validate → use loop

A leaked string is not a finding on its own. Run the loop:

  1. Recover — pull the artifact and extract the candidate secret.
  2. Validate — identify what it is (API key? DB password? signing key? token?) from its prefix/format and where it appeared.
  3. Use — supply it to the thing it unlocks and confirm access changes. Impact you can demonstrate is the report; a string you cannot use is noise.

Grep the client for secrets

# pull every JS bundle and its sourcemap, then grep for key-shaped strings
curl -s https://cwap.thexssrat.com/m08/static/app.js | grep -Ei "key|token|secret|api"
# sourcemaps expand minified bundles back to original files + comments
#   look for //# sourceMappingURL=... then fetch the .map

# entropy / pattern hunting across responses
trufflehog filesystem ./loot   #  or:  gitleaks detect --source ./loot
grep -RniE "(AKIA|glpat-|xox[bp]-|rk_live_|-----BEGIN|password|secret_key)" ./loot

Source control is a time machine

# exposed .git? dump the whole repo, then walk history
git-dumper https://cwap.thexssrat.com/m08/.git/ ./repo
cd repo && git log --oneline --all
git log -p -S PASSWORD            # find the commit that added/removed a secret
git show <old-commit>:config.py  # a “removed” secret is still in history

Config, debug & API surfaces

# classic leak locations to always try
curl -s .../.env            # DB creds, APP_KEY
curl -s .../settings.py.bak # hardcoded SECRET_KEY
curl -s .../actuator/env    # Spring-style config/credential dump
curl -s .../openapi.json    # hidden endpoints + example keys
# force a stack trace with bad input -- debug pages love printing config
curl -s ".../api/lookup?id=not-an-int"

Prove it — use the key

When you recover an API key, don’t just log it: find the endpoint it authorizes and call it. This lab has a gated admin API that stays 401 until you present the correct recovered key. That transition from denied to authorized is the finding.