Post

Server-side request forgery (SSRF) module - Web Security Academy - PortSwigger

Server-side request forgery (SSRF) module - Web Security Academy - PortSwigger

Brief introduction

Server-side request forgery (SSRF) is a web security vulnerability that allows attacker to cause the server-side application to make a request to an unintended location. In a typical SSRF attack, the attacker might cause the server to make a connection to internal-only services within the organization’s infrastructure. In other cases, they may be able to force the server to connect to arbitrary external systems. This could leak sensitive data, such as authorization credentials.

Common SSRF attack

SSRF attacks against the server

In this type of SSRF attack, the hacker tries to cause the server-side application to make a HTTP request back to the internal server that is hosting the application, via its loopback address. This typically involves supplying a URL with a hostname like 127.0.0.1, localhost, or other ways to express the internal server (decimal, IPv6, 0-reduced IP format, …).

For example, imagine a shopping application that lets the user view whether an item is in stock in a particular store. To provide the stock information, the application must query various back-end REST APIs. It does this by passing the URL to the relevant back-end API endpoint via a front-end HTTP request. When a user views the stock status for an item, their browser makes the following request:

POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1

This causes the server to make a request to the specified URL, retrieve the stock status, and return this to the user. In this example, an attacker can modify the request to specify a URL local to the server:

POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://localhost/admin

If there’s not any sanitization on the submitted URL, the server fetches the contents of /admin and returns it to the user. Normally, the attacker can visit to the URL /admin, but cannot access any information because of user privilege. But in the case of a SSRF attack via URL, the request comes from the local machine, the normal access controls are bypassed.

Lab: Basic SSRF against the local server: This lab has a stock check feature which fetches data from an internal system. To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.

Solution:

image

Click “Check stock”, there’s a POST request appeared. In this request, there’s a parameter called stockAPI, with a URL attached. We just need to change the URL to http://localhost/admin. Then, a screen with user deleting options appeared. Click “delete” carlos, then the URL is changed to /admin/delete?username=carlos. Change the URL in stockAPI again, then the lab is solved!

SSRF attacks against other back-end systems

Besides local machine, a SSRF attack can cause unallowed access to other back-end servers in local network. For example, the URL in stockAPI is changed into http://192.168.0.68/admin, which is a private IP address that normal users are not accessible.

POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://192.168.0.68/admin

Lab: Basic SSRF against another back-end system: This lab has a stock check feature which fetches data from an internal system. To solve the lab, use the stock check functionality to scan the internal 192.168.0.X range for an admin interface on port 8080, then use it to delete the user carlos.

Click “Check stock”, and then, send the POST request to Intruder. Setting up a brute-force attack to find out the number X (from 1 to 255).

image

The rest part is the same as the previous lab.

Circumventing common SSRF defenses

Some applications will have mechanisms to prevent SSRF attacks.

SSRF with blacklist-based input filters

Some applications block input containing hostnames like 127.0.0.1 and localhost, or sensitive URLs like /admin. In this situation, you can often circumvent the filter using the following techniques:

  • Use an alternative IP representation of 127.0.0.1, such as 2130706433 (decimal), 017700000001 (octal), or 127.1 (0 is auto filled after processed).

  • Register own domain name that resolves to 127.0.0.1.

  • Obfuscate blocked strings using URL encoding or case variation.

  • Provide a URL that in control, which redirects to the target URL. Try using different redirect codes, as well as different protocols for the target URL. For example, switching from an http: to https: URL during the redirect has been shown to bypass some anti-SSRF filters.

Lab: SSRF with blacklist-based input filter: This lab has a stock check feature which fetches data from an internal system. To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos. The developer has deployed two weak anti-SSRF defenses that you will need to bypass.

Try exploit SSRF by testing all methods above. We can see that alternative IP address representations like 127.1, 2130706433, … are all blocked, aside with URL-encoding and the keyword admin. Try making a double URL-encoding, then http://localhost/admin becomes:

http://%25%36%43%25%36%46%25%36%33%25%36%31%25%36%43%25%36%38%25%36%46%25%37%33%25%37%34/%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45

Send the request and we can see that this payload can bypass the prevention. The rest steps are the same as the previous labs.


Some applications only allow inputs that match a whitelist of permitted values. The filter may look for a match at the beginning of the input, or contained within in it. Some methods to bypass this type of filter:

  • Embed credentials in a URL before the hostname using @ character: http://expected-host:fakepassword@evil-host. If the filter only checks if the URL begins with http://expected-host (in whitelist), the filter may be bypassed, although the real destination is evil-host.

  • Use the # character to indicate a URL fragment. For example: https://evil-host#expected-host. The character # indicates that the rest part after it is not sent to the back-end, but the filter has checked and allow it because the expected-host is matched with the whitelist.

  • Leverage the DNS naming hierarchy to place required input into a fully-qualified DNS name that in fully control. For example: https://expected-host.evil-host.

  • URL encoding, double encoding.

Lab: SSRF with whitelist-based input filter: This lab has a stock check feature which fetches data from an internal system. To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos. The developer has deployed an anti-SSRF defense you will need to bypass.

image

Try sending the request with a random URL, we can obtain a message that the host must be stock.weliketoshop.net. Let’s try some methods that are discussed above. Using the URL: http://localhost@stock.weliketoshop.net (In this case, localhost is a username). The application returns 500, which indicates that the server has made attempts to send request to the user called localhost.

Now, let’s continue with the URL payload: http://localhost#@stock.weliketoshop.net. The reason why we add a # before the URL is that it can cause the following path commented. But in this case, the original message comes again, which requires the host must be in whitelist. It indicates that the URL parser using really triggers the hash character as a comment indicator. Now, try double encode the # (%2523), in this case the application returns 200 and the response also contains Admin panel.

image

This means this payload is successful to bypass the URL parser’s filter, which simply checks the legal host. But when this URL sent to the back-end server, the hash character is decoded and the rest part of the URL is not sent, so the application access local machine via localhost.

Now, I find out a way that we should add the /admin path to the end of the URL and access to the admin panel.

(Disclaimer: I’m currently not understand clearly the reason why this way works. Because, in normal cases, the following part after hash character is not sent, including the /admin path, but in this case it works well. Currently, the reason in my mind is the lab’s server treats the path and parameter as a separated part, so it is not affected by the hash character).

Bypassing SSRF filters via open redirection

Sometimes, it is possible to bypass system’s filter by using open redirection. For example, the application has a functionality which allows users to send request to the URL that is entered by user. The application also has a whitelist filter, only allows a domain (For example: http://request-domain.net), for preventing from SSRF attack.

But in this case, the application also has a functionality like this: /product/nextProduct?currentProductId=6&path=http://evil-user.net. When accessing, the server automatically redirect the user to the defined URL in path.

Lab: SSRF with filter bypass via open redirection vulnerability: This lab has a stock check feature which fetches data from an internal system. To solve the lab, change the stock check URL to access the admin interface at http://192.168.0.12:8080/admin and delete the user carlos. The stock checker has been restricted to only access the local application, so you will need to find an open redirect affecting the application first.

image

On each product, there’s a functionality that allows user to go to the next product. In the HTTP proxy, we can see a request that is vulnerable to exploit SSRF bases on open redirection vulnerability. There’s an endpoint called /product/nextProduct with a parameter named path that we can inject the “evil” URL, maybe without any sanitization from application.

Change the stockApi URL to this endpoint: stockApi=/product/nextProduct?path=http://192.168.0.12:8080/admin. Then follow the same steps as previous labs.

Blind SSRF vulnerabilities

This type of SSRF is also the same as discussed, but in this case, the response from back-end is not returned to front-end. The most common way to detect blind SSRF vulnerabilities is using out-of-band techniques. This involves attempting to trigger an HTTP request to an external system that in fully control, and observe the network interactions between the website and external system.

Lab: Blind SSRF with out-of-band detection: This site uses analytics software which fetches the URL specified in the Referer header when a product page is loaded. To solve the lab, use this functionality to cause an HTTP request to the public Burp Collaborator server.

Click on any product, change the Referer header in HTTP request to the domain generated by Burp Collaborator.

image

This post is licensed under CC BY 4.0 by the author.

Trending Tags