服务端请求伪造(SSRF)
翻译
原文:https://portswigger.net/web-security/ssrf
- name: 翻译
desc: 原文:https://portswigger.net/web-security/ssrf
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 0服务端请求伪造(SSRF)
在本节中,我们将解释什么是服务端请求伪造,随后描述一些常见的示例,并解释如何发现和利用各种 SSRF 漏洞。
# 1什么是SSRF?
服务端请求伪造(也称为 SSRF)是一个 Web 安全漏洞,它允许攻击者诱导服务器端应用程序 向非预期位置发出请求。
在典型的 SSRF 攻击中,攻击者可能会使服务器 连接到组织架构中的其他内部服务。在某些情况下,他们能够强制服务器连接到任意外部系统,从而泄露授权凭据等敏感数据。
实验室
如果您已经熟悉 SSRF漏洞 背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么您可以从下面的链接访问本主题中的所有实验室。
# 2SSRF漏洞会造成什么影响?
成功的 SSRF 攻击通常会导致 对组织内部数据 的未授权访问/操作,无论是在易受攻击的应用程序自身,还是在应用程序可以与之通信的其他后端系统上都是如此。在某些情况下,SSRF 漏洞可能允许攻击者执行任意命令。
导致连接到外部第三方系统的 SSRF 漏洞利用,可能会产生恶意的后续攻击,这些攻击来源于 托管易受攻击应用程序的组织。
# 3常见的SSRF攻击
SSRF 攻击通常会利用信任关系,从而升级 来自脆弱应用程序 的攻击,并执行未经授权的操作。这些信任关系可能与服务器自身有关,也可能与同一组织内的其他后端系统有关。
# 3.1针对服务器自身的 SSRF 攻击
在针对服务器自身的 SSRF 攻击中,攻击者诱导应用程序并通过其环回网络接口 向 托管应用程序的服务器发出 HTTP 请求。这通常需要提供一个带有主机名的 URL,如127.0.0.1
(指向环回适配器的保留 IP 地址)或localhost
(同一适配器的常用名称)。
例如,假设有一个购物应用程序,它允许用户查看 特定商店中的某个商品 是否有库存。为了提供库存信息,应用程序必须查询各种后端 REST API,查询的具体信息取决于 相关产品和商店 这两个参数。该函数是通过前端 HTTP 请求将 URL 传递到相关的后端 API 端点来实现的。因此,当用户查看商品的库存状态时,他们的浏览器会发出如下请求:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1
2
3
4
5
这将导致服务器向指定的 URL 发出请求,以检索库存状态,并将其返回给用户。
在这种情况下,攻击者可以修改请求,指定服务器自身的本地 URL。例如:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://localhost/admin
2
3
4
5
如此一来,服务器将获取/admin
的内容并将其返回给用户。
当然,现在攻击者可以直接访问/admin
这个URL。但,管理功能通常只有 经过身份验证的合法用户 才能访问。因此,直接访问 URL 的攻击者不会看到任何感兴趣的内容。但是,当对/admin
的请求来自本地计算机自身时,将绕过正常的访问控制 (opens new window)。应用程序将授予其对管理功能的完全访问权限,因为请求似乎来自受信任的位置。
- name: 实验室-学徒
desc: 针对本地服务器的基本SSRF >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-basic-ssrf-against-localhost
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
为什么应用程序会以这种方式运行,并隐式信任来自本地计算机的请求?出现这种情况的原因有很多种:
- 访问控制检查 位于 应用程序服务器的前面,在不同的组件中实现。当连接回到服务器本身时,将绕过检查。
- 出于灾备恢复目的,应用程序可能允许来自本地计算机的任何用户 在不登录的情况下 进行访问和管理。这为管理员提供了一种 在丢失凭据时 恢复系统的方法。这里的假设是,只有完全受信任的用户才会直接来自服务器自身。
- 管理面板监听的端口号 可能与 主应用程序不同,因此用户可能无法直接访问。
在这种信任关系中,来自本地机器的请求 与 普通请求的处理方式不同,这通常是 SSRF 成为严重漏洞的原因。
# 3.2针对其他后端系统的 SSRF 攻击
服务器端请求伪造 经常出现的另一种信任关系是,应用程序服务器 能够 与用户无法直接访问的其他后端系统进行交互。这些系统通常具有不可路由的私有 IP 地址。由于后端系统受到网络拓扑的保护,因此它们通常具有较弱的安全态势。在许多情况下,内部后端系统包含敏感功能,任何与系统交互的人 都可以在没有身份验证的情况下访问这些功能。
在前面的示例中,假设在后端 URL https://192.168.0.68/admin
处有一个管理界面。在这里,攻击者可以利用 SSRF 漏洞,通过提交以下请求来访问管理界面:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://192.168.0.68/admin
2
3
4
5
- name: 实验室-学徒
desc: 针对其他后端系统的基本SSRF >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-basic-ssrf-against-backend-system
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
# 4绕过常见的 SSRF 防御
有时,你会看到包含 SSRF 行为的应用程序,以及该程序旨在防止恶意利用的防御措施。通常,这些防御是可以被绕过的。
# 4.1基于黑名单的输入过滤器 中的SSRF
一些应用程序会阻止包含主机名(如127.0.0.1
和localhost
)或敏感 URL(如/admin
)的输入。在这种情况下,你通常可以使用各种技术来绕过这个过滤器:
- 使用
127.0.0.1
的替代 IP 表示形式,例如2130706433
、017700000001
或127.1
。 - 注册你自己的域名,将其解析为
127.0.0.1
。你可以使用spoofed.burpcollaborator.net
来实现此目的。 - 使用 URL 编码或大小写等变体,对被阻止的字符串进行模糊处理。
- 提供由你控制的 URL,该 URL 随后会重定向到目标服务器的 URL 。尝试对目标 URL 使用不同的重定向代码 以及 不同的协议。例如,在重定向期间,从
http://
切换到https://
的 URL 已被证明可以绕过一些防 SSRF 的过滤器。
- name: 实验室-从业者
desc: 基于黑名单的输入过滤器 中的SSRF >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-ssrf-with-blacklist-filter
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 4.2基于白名单的输入过滤器 中的SSRF
一些应用程序只能输入白名单中允许的值,例如 与???匹配、以???开头、包含???字符 等规则。
一些应用程序只允许与允许值的白名单匹配、开头或包含允许值的白名单的输入。在这种情况下,你有时可以利用 URL 解析中的不一致来绕过这个过滤器。
在实现 URL 的临时解析和验证时,URL 的规范中包含许多容易被忽视的功能:
- 你可以在主机名之前的 URL 中嵌入凭据,这需要用到
@
字符。例如:https://预期主机名:假密码@恶意主机名
- 你可以使用字符
#
来指示 URL 片段标识符(锚点)。例如:https://恶意主机名#预期主机名
- 你可以利用 DNS 命名层次结构,将所需的输入拼接到你控制的完全限定域名(FQDN)中。例如:
https://预期主机名.恶意主机名
- 你可以对字符进行 URL 编码以混淆 URL 解析代码。如果实现过滤器的代码在处理 URL 编码字符时,与执行后端 HTTP 请求的代码处理方式不同,则这一差异特别有用。请注意,你也可以尝试对字符进行双重编码 (opens new window); 一些服务器会递归地对它们接收到的输入进行 URL 解码,这可能会导致进一步的差异。
- 你还可以将以上技术结合使用。
- name: 实验室-专家
desc: 基于白名单的输入过滤器 中的SSRF >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-ssrf-with-whitelist-filter
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
# 4.3通过开放重定向绕过SSRF过滤器
(译者加:开放重定向(Open Redirect),又被称为 URL跳转漏洞)
有时可以通过利用 开放重定向漏洞 来规避任何类型的基础过滤器防御。
在前面的 SSRF 示例中,假设用户提交的 URL 经过严格验证,以防止恶意利用 SSRF 行为。但是,允许该 URL 的应用程序包含一个开放重定向漏洞。如果用于生成后端 HTTP 请求的 API 支持重定向,则可以构造一个满足过滤器的 URL,并将请求重定向到所需的后端目标。
例如,假设应用程序包含一个开放重定向漏洞,漏洞存在于以下 URL 中:
/product/nextProduct?currentProductId=6&path=http://evil-user.net
响应将会重定向到:
http:
你可以利用开放重定向漏洞绕过 URL 过滤器,并在其中利用 SSRF 漏洞,如下所示:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
stockApi=http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin
2
3
4
5
此 SSRF 漏洞利用之所以有效,是因为应用程序首先验证提供的stockAPI
URL 是否位于允许的域中,而该域确实如此。然后,应用程序将请求所提供的 URL,这将触发开放重定向。随后,应用程序将跟随重定向,并向攻击者选择的内部 URL 发出请求。
(以下为译者加,上述攻击流程的大致步骤):
- 网站
weliketoshop.net
的path
参数中存在一个开放重定向漏洞; - 攻击者向
weliketoshop.net
发送构造好的URL --> - 应用程序验证
stockApi
URL中的域名,域名来自网站自身,符合条件,允许通过 --> - 应用程序向
weliketoshop.net
发出请求 --> - 应用程序触发
path
中的重定向漏洞并向http://192.168.0.68/admin
发出请求。
- name: 实验室-从业者
desc: 通过开放重定向绕过SSRF过滤器 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-ssrf-filter-bypass-via-open-redirection
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 5盲SSRF漏洞
(译者加:无回显的 SSRF 漏洞)
当可以诱导应用程序向提供的 URL 发出后端 HTTP 请求时,如果后端请求的响应 不会在应用程序的前端页面中返回,就会出现盲 SSRF 漏洞。
盲 SSRF 通常更难被利用,但有时会导致 在服务器或其他后端组件上 完成远程代码执行。
# 6寻找SSRF漏洞的隐藏攻击面
许多服务端请求伪造漏洞相对容易发现,因为应用程序的正常流量中涉及包含完整 URL 的请求参数。SSRF 的其他例子发现难度较大。
# 6.1请求中的部分URL
有时,应用程序仅将主机名或部分 URL 路径放入请求参数中。然后,提交的值将在服务器端合并到完整的 URL 中。如果该值很容易被识别为主机名或 URL 路径,则潜在的攻击面会很明显。但是,作为完整 SSRF 的可利用性可能会受到限制,因为你无法控制所请求的整个 URL。
# 6.2数据格式中的URL
一些应用程序 以某种规范格式 来传输数据,在其规范格式中,可能包含数据解析器的请求 URL 。一个明显的例子是 XML 数据格式,它被广泛用于 Web 应用程序中,以将结构化数据从客户端传输到服务器。当应用程序接收 XML 格式的数据并对其进行解析时,它可能容易受到XXE注入 (opens new window)的攻击,进而容易受到 通过XXE实现的SSRF攻击。在后续学习XXE注入 (opens new window)漏洞时,我们将更详细地介绍这一点。
# 6.3通过Referer标头实现的SSRF
一些应用程序会采用服务器端分析软件,来跟踪访问者信息。该软件通常会在请求中记录 Referer 标头,因为这对于 跟踪传入的链接 特别有效。一般情况下,分析软件实际上会访问 Referer 标头中出现的任何第三方 URL 。这样做是为了分析引用站点的内容,包括该链接中使用的锚文本。因此,Referer 标头通常代表 SSRF 漏洞的卓效攻击面。有关于 Referer 标头的漏洞示例,请参阅盲SSRF漏洞 (opens new window)。
一些应用程序采用跟踪访问者的服务器端分析软件。该软件经常在请求中记录Referer头,因为这对跟踪传入链接特别有用。通常情况下,分析软件实际上会访问Referer头中出现的任何第三方URL。这通常用于分析引用站点的内容,包括传入链接中使用的锚文本。因此,Referer标头通常代表SSRF漏洞的富有成效的攻击面。有关涉及Referer标头的漏洞示例,请参阅Blind SSRF漏洞。