Exploiting and Remediating SSRF Vulnerabilities with Portswigger
Today, we’ll be exploring one of my favorite SSRF vulnerabilities! We’ll dive into the methodology behind testing for SSRF from both a black box as well as white box perspective and demonstrate how the attack works through Portswigger labs. Let’s go!
How SSRF Works
Server-Side Request Forgery (SSRF) is a vulnerability that allows an attacker to manipulate a server into making unintended requests to internal or external resources. This could include accessing internal services, such as admin portals on localhost, or making external connections to attacker-controlled servers. SSRF typically exploits the trust relationship between the server and its environment, often due to insufficient input validation or overly permissive configurations.
SSRF was ranked number 10 on the OWASP Top 10:2021 which is a list maintained by OWASP to publish the most critical security risks impacting web applications. If you want to learn more about the OWASP Top 10, read my blog post on it!
Testing Approach
Black-Box Testing Methodology
- Map the application
- Walk through every page accessible within the user context and note every input vector that may talk to the backend (identify any request parameters that contain hostnames, IP addresses or full URLs) while Burp is running
- For each request parameter, modify its value to specify an alternative resource and observe how the application responds
- Circumvent with payloads to work around blacklists or exploit whitelists with URL parsing
- To test for a request to an external resource, modify its value to a server on the internet that you control and monitor the server for incoming requests (use Burp Collaborator or a publicly available web server you own) to test for blind SSRF
White-Box Testing Methodology
- Review source code and identify all request params that accept URLs and search for URL Parameter names or functions in the code and see if there are any defenses avail to circumvent
- Determine what URL parser is being used and if it can be bypassed
Now that we’ve defined what SSRF is and how to test for the vulnerability from a black box and white box standpoint, let’s utilize Portswigger’s labs to demonstrate the different ways to bypass common protection mechanisms that a web application may put in place to mitigate SSRF.
Basic SSRF Against the Local Server
- Let’s explore the product stock feature by checking the stock of any item
- When we observe the HTTP requests made in the HTTP history tab, we can see a request made to the internal server
- The response is the stock quantity for the item from the sever and a POST request is made with the
stockAPI
parameter making a request tohttp://stock.weliketoshop.net:8080/product/stock-check/store
- So let’s modify the parameter to actually point to the admin portal located on the internal host – as the application is implicitly trusted
- Delete Carlos leads to a 302 redirect /admin
Basic SSRF Against Another Back-End System
In some scenarios, The application server is able to interact with backend systems that are not directly reachable by users and often have non-routable private IPs
- Send the URL-encoded payload in the
stockAPI
parameterhttp://192.168.0.§1§:8080/admin
and highlight the last octet of the IP address as we’ll be fuzzing this subnet to find where the admin panel resides - In payloads tab set the payload type to numbers in sequential order from 0-255
- If we look at the results of the intruder attack and filter by status code – we see
192.168.0.148
was the successful payload and the response displays the admin panel - Forward that request to Burp repeater in order to confirm our access to the admin panel
- Now we can issue subsequent requests such as making a request to delete Carlos
SSRF with Backlist-based Input Filter
Some applications block input containing hostnames like 127.0.0.1 or localhost or sensitive URLs /admin
Examples of Bypass Techniques:
- Use alternative IP representation of 127.0.0.1
- PayloadAllTheThings – Utilize a repository of payloads
- Register your own domain name that resolves to 127.0.0.1 / use spoofed.burpcollaborator.net
- Obfuscate blocked strings using URL encoding or case variation
- Provide a URL you control that redirects to the target URL
- Try using different redirect codes as well as different protocols for the target URL – switching from an
http:
tohttps:
URL during the redirect has been shown to bypass some Anti-SSRF filters
- For this lab, the application blacklisting any external requests made toe
http://127.0.0.1
so I found a bypass by using an alternative,http://127.0.1/
- When I try to access
http://127.0.0.1/
I get a denial so I double-encoded thea
in/admin
and was able to bypass the filter. As we have no access to the source code and approaching the application from a black box testing method, we have to experiment and figure out the blacklist filter ourselves. It seems in this case, the filter is checking to see that 127.0.0.1 or/admin
is not utilized, but did not provide coverage for use cases where an attacker would use an alternative to the localhost IP address or an encoded variation of the/admin
endpoint. - So now we can continue to delete Carlos’ account yet again like a menace
Circumventing Whitelist-Based Input Filters
In this application, the developers decided to implement a whitelist which is an allow list of inputs that match. The filter may look for a match at the beginning of the input or contained within it. We can bypass this by exploiting inconsistencies in URL parsing
Techniques:
- Embed credentials in a URL before the hostname using @ to circumvent whitelists checking for the beginning of the input
https://expected-host:fakepassword@evil-host
- Use
#
character to indicate a URL fragment
https://evil-host#expected-host
- Leverage DNS naming hierarchy to place required input into a fully qualified DNS name that you control
https://expected-host.evil-host
- URL encode characters or double encoding
Bypass SSRF Filter via Open Redirect
- In this application, the whitelist is checking for the API call utilized in the
stockAPI
parameter making a request to the expected location (/product/nextProduct?path
). We further exploit this call by passing in the URL of the admin portal as the value topath
. - We can now abuse this SSRF vulnerability by making a call to delete the account of Carlos
Mitigation
- Sanitize and validate all client-supplied input data
- Enforce URL schema, port and destination with a positive allow list
- Do not send raw responses to client
- Disable HTTP redirections
- Do not use black list filters or regex – Attackers can bypass these filters as they’re not comprehensive and mindful of every possible use case for a bypass