HTB CWES study materials
HTB CWES study resources

Redirect-Following SSRF and the Scope Line at an Internal Jenkins

HTB CWES · Put your knowledge to work in context.

All case studies

Redirect-Following SSRF and the Scope Line at an Internal Jenkins

A project-management SaaS offers a "link preview" feature. POST /api/preview with {"url":"https://..."} returns the page title and first image. The fetch service runs on a separate host with broad egress, including to the internal 10.20.0.0/16 network. Direct requests to http://169.254.169.254/latest/meta-data/ return 403 and a 2-second timeout, consistent with IMDSv2 enforcement. gopher:// and file:// are rejected, but HTTP redirects are followed up to five hops. A URL pointing to http://10.20.30.15:8080/ returns 200 with the title "Dashboard [Jenkins]". The app's own egress is restricted, so you cannot reach that host directly. DNS rebinding is possible but takes time. You have 8 hours and authorization for SSRF proof, not for exploiting internal services.

1. Is the metadata 403 a dead end? Explain what you can and cannot conclude, and what you would test next.

Read the worked answer

The 403 is not conclusive. IMDSv2 requires a PUT to /latest/api/token; the preview feature only issues GETs, so even a reachable IMDS would return 403 to a GET on metadata paths. The 2 s timeout also suggests the request may be blocked by the fetch service's egress policy rather than by AWS. What you can conclude: this SSRF cannot directly read IMDSv1 credentials. What you cannot conclude: that the host has no instance role or that internal networking is blocked.

Next tests: (1) IPv6 metadata http://[fd00:ec2::254]/latest/meta-data/; (2) alternate names such as http://instance-data/latest/meta-data/; (3) a redirect from your server to the metadata IP, since redirects are followed; (4) a non-metadata internal host to distinguish "metadata blocked" from "all internal blocked" - the Jenkins title already shows internal reachability. Do not spend the window on IMDSv2 if you cannot send PUT.

2. Design a safe, convincing proof of SSRF to the Jenkins host, including how to handle redirects and DNS rebinding.

Read the worked answer

Safe proof: stand up https://collab.example/r returning 302 Location: http://10.20.30.15:8080/. Submit {"url":"https://collab.example/r"}. The preview fetcher follows redirects and returns the Jenkins title, proving server-side access to an internal host from the fetcher's network position, not yours. Use a unique path (/r/<random>) and log the fetcher's source IP and User-Agent.

DNS rebinding is a fallback, not the first move: it requires the fetcher to resolve the same hostname twice with different answers and to keep the connection, which is timing-dependent. Redirects are deterministic and easier to evidence. For a stronger proof, redirect to a harmless internal endpoint that returns a known string, not to /script or any state-changing URL. Capture the response body/title and the collaborator log; that is enough to show SSRF with internal network access.

3. The Jenkins login page is reachable. Where is the line between proving SSRF impact and out-of-scope exploitation, and what would you report?

Read the worked answer

The line: proving SSRF means demonstrating that the server can be made to issue a request to a destination you cannot reach, and that the response is observable. Fetching the Jenkins login page or a static asset is proof. Using Jenkins to run a build, reading credentials, or hitting /script is exploitation of a second system and is out of scope unless explicitly authorized. The absence of authentication on /script would make it tempting, but "reachable" is not "authorized."

Report: "The link-preview fetcher follows attacker-controlled redirects and can reach internal RFC1918 hosts, including 10.20.30.15:8080 (Jenkins). This gives an external attacker a foothold into the internal network and could be chained to unauthenticated Jenkins RCE if that service is exposed." Include the redirect chain, the fetcher IP, the returned title, and the time. Remediation: allowlist destinations after DNS resolution, block redirects to new hosts, deny RFC1918/link-local, enforce IMDSv2, and run the fetcher in a segmented egress network.