Following a Config Pointer to an Environment File to Leak an Admin Token
Le défi
Vous avez un shell sur app01 en tant qu'utilisateur nginx. La configuration de l'appli ne stocke pas le jeton admin directement - elle le lit depuis un fichier d'environnement quelque part sur le disque. Suivez la piste depuis la config jusqu'a ce fichier et soumettez le jeton admin.
Ce que tu vas apprendre
- Recognise when a config file references a secret instead of holding it
- Locate a systemd EnvironmentFile and the env file it loads
- Read an env file to extract a credential like ADMIN_TOKEN
- Use grep across /etc to find a secret when the path is not obvious
- Apply the fix: load secrets from a vault or scoped secret store at runtime
Compétences testées
Prérequis
- Comfortable with basic shell commands (ls, cat, grep)
- Can read a Python config file and a systemd service unit
Comment ça marche
Mature apps try not to hardcode secrets directly in source. Instead the code reads a secret from the process environment, and something else - a systemd unit, a Docker env_file, or a shell wrapper - is responsible for putting that value into the environment at start-up. In this challenge config.py calls os.environ.get('ADMIN_TOKEN') and even leaves a breadcrumb: SECRET_ENV_PATH = '/etc/acme/secret.env'. The secret is real, it is just one file away.
That indirection improves hygiene in version control - the repository never contains the token - but it does nothing once an attacker has read access to the host. The env file still sits on disk in plain text, and the service unit declares exactly where: EnvironmentFile=/etc/acme/secret.env. Anyone who can read that path reads the token. A foothold as the service user is usually enough, because the file has to be readable by that very user for the service to start.
The skill being exercised is chaining one artifact to the next: a config that names a path, a service unit that confirms the path, and finally the env file that holds the value. When the path is not spelled out, a recursive grep such as grep -r ADMIN_TOKEN /etc jumps straight to the line. The token is stored in clear text because the app must send it verbatim, so reading the file is all it takes.
Erreurs fréquentes
- Stopping at the config file.
config.pydoes not contain the token - it only names the path. Solvers who grep just the app directory miss the secret entirely. - Ignoring the service unit. The systemd unit's
EnvironmentFile=line is the strongest pointer to where the secret is loaded from; skipping/etc/systemdmeans guessing. - Assuming /etc is off-limits. The env file must be readable by the service user, so a low-privilege shell as that user can usually read it.
- Grepping for the wrong keyword. Searching for
passwordfinds the DB password, not the admin token - grep forADMIN_TOKENspecifically.
Comment s'en protéger
Moving a secret from source into an on-disk env file is a half-measure; the durable fix keeps the value off the host filesystem entirely:
- Fetch the token at start-up from a secret manager - a vault service or your cloud provider's secrets store - and hold it only in process memory.
- If an env file is unavoidable, lock it down with
chmod 600and a dedicated owner so a compromised service user cannot read it. - Scope and rotate the token so a single leak is short-lived and limited in blast radius.
- Audit reads of secret paths and alert on access from unexpected users or processes.
Treat any token that has touched a readable file on a shared host as already burned: rotate it and reissue, since deleting the file does not undo a read that already happened.