IMDSv2 Bypass Techniques Hunters Still Use on SSRF
Getting a raw GET to 169.254.169.254 is rare now. Teams turned on IMDSv2 and dropped the hop limit. That does not mean metadata is dead for hunters — it means the bypass work moved into method control, headers, and how the victim HTTP client parses URLs.
This is for authorized SSRF on in-scope targets and labs. Prove reachability; do not dump production role keys into a public report.
What “bypass” actually means here
You are not cracking AWS crypto. You are finding a fetch sink that can:
- Issue a
PUT(or another verb the client maps oddly) to/latest/api/token - Attach
X-aws-ec2-metadata-token-ttl-seconds - Reuse
X-aws-ec2-metadata-tokenon later GETs - Reach the link-local address despite filters
If the SSRF is GET-only with no custom headers, many IMDSv2 fleets stop you. Keep notes on which constraint failed — that detail sells the finding.
Technique map I use on live targets
1) Method and header forging
Webhook exporters, “preview URL,” and image fetchers sometimes expose verb + header maps meant for API clients. Try forcing PUT with the TTL header. Some sinks only allow a fixed allowlist of headers — if X-aws-ec2-metadata-token is missing from that list, stop and reframe as “SSRF cannot complete IMDSv2.”
2) Hop-limit awareness
AWS documents a hop limit (often 1) so containers and SSRF proxies never see IMDS. An empty or reset response after a correct token request often means network policy, not a bad payload. Screenshot that difference: collaborator works, metadata does not. Defenders care; some programs still pay for internal SSRF even without creds.
3) Parser disagreement
Blacklists that string-match 169.254 miss decimal, hex, IPv6-mapped, and DNS names that resolve to link-local inside the VPC. Test forms the app normalizes differently than the downstream client. PortSwigger’s SSRF material covers the classic encoding games; pair them with IMDSv2’s two-step flow instead of a single GET.
4) Open-redirect trampolines
When the sink only follows “trusted” hosts, an open redirect on an allowlisted domain can bounce to metadata. You need a sink that follows redirects and preserves method/headers across hops — many do not. Document redirect depth and header stripping honestly.
5) Alternate metadata paths
Besides the well-known IPv4 link-local, look for environment-specific metadata endpoints (other clouds, container metadata) once you confirm egress. Same playbook: can you set headers and verbs?
Proof shape that clears triage
- Sink location (param, PDF fetch, import job)
- Collaborator hit proving outbound HTTP
- Token
PUTattempt with response codes - Either a lab credential path or a clear hop-limit block
- Blast-radius note tied to role scope if you safely inspected a sandbox role
AWS’s instance metadata docs and CWE-918 (SSRF) are solid citations. Recommend IMDSv2 required, hop limit 1, and egress deny to link-local from app workers.
I treat IMDSv2 less like a wall and more like a checklist: verb, headers, hops, parser. The bugs that still pay live in the gaps between those four.