SSRF攻击示例和缓解措施
服务器端请求伪造(SSRF)是一种可以用来使应用程序发出任意HTTP请求的攻击。攻击者使用 SSRF 将来自互联网上暴露的服务和 Web 应用程序的请求代理到未暴露的内部终端。SSRF是一个黑客反向代理,这些任意请求通常以内部网络终端为目标,以执行从侦察到完成帐户接管的任何操作。SSRF以及XSS和CSRF,由于其普遍性和影响,已成为了最严重的web安全漏洞,SSRF是owasp十大漏洞之一。
什么是 SSRF?
乍一看,添加从应用程序发出HTTP请求的功能似乎不需要进行安全审查。但是,只要你允许用户控制HTTP请求的目标并提供用户输入,攻击者就可以利用你的应用程序在内部网络中的特权位置来实施攻击。
SSRF漏洞
Webhook就是一个很好的例子。通过设计,开发者希望用户能够控制webhook的目标地址。然而,这意味着攻击者也可以控制目标地址。这允许攻击者通过攻击者控制的 DNS 直接针对内部 IP 地址或内部地址。
这意味着,无论你对敏感的内部服务或应用程序进行多么严格的防火墙防护,如果你允许公开暴露的应用程序访问这些内部应用程序并让攻击者控制 HTTP 请求目标,攻击就有可能找到通往这些敏感应用程序的路径。
利用SSRF
SSRF
让我们从一个充当在线 hexdump 的简单示例应用程序开始。应用程序接受 URL,向 API 发出请求,并输出响应正文的十六进制转储。你可以在下图中看到示例输出以及此应用程序的源代码。
HTTP hexdump 应用程序的示例输出
但是,如果这个 hexdump 应用程序可以通过网络访问敏感的内部应用程序,会发生什么情况?例如,你可能正在遵循最佳实践并使用内部秘密服务来安全地存储应用程序所需的凭证,而不是将它们检入源代码中。
这正是上图中的程序所模拟的。要运行此应用程序,请将上图中的代码保存在一个名为 ssrf1.go 的文件中,然后输入go run ssrf1.go 以运行该应用程序。
首先导航到 http://localhost:8080?url=http://www.google.com 的应用程序以查看 www.google.com 的 hexdump。要触发 SSRF,请导航到 http://localhost:8080?url=http://localhost:8081 以获取内部秘密。
一个典型的SSRF漏洞示例
上图中的程序运行 hexdump 应用程序并模拟秘密服务的运行。虽然 hexdump 应用程序绑定到所有接口,但秘密服务只绑定到loopback,这是一个不应该暴露在互联网上的合理决定。
问题是 hexdump 在本地运行并且可以向loopback(或任何其他内部终端)发出请求。只需将 hexdump 指向 http://localhost:8081 即可公开内部凭证,无论它是否侦听任何公开公开的接口。
AWS上的SSRF
AWS示例元数据服务 (IMDSv1) 很好地说明了 SSRF 的强大功能。事实上,研究人员Colin Percival称其为EC2最危险的功能。
示例元数据服务非常有趣,因为它可以同时用于增提高和降低应用程序的安全性。
它可用于通过帮助你安全地管理秘密凭证生命周期来提高应用程序的安全性。你可以将 IAM 角色附加到运行你的应用程序的示例,然后从示例元数据终端获取你的凭证。示例终止后,这些凭证将被销毁并颁发一组新凭证。从理论上讲,这有助于秘密凭证的生命周期;它减少了可能在违规中暴露的凭证数量,并将凭证的生命周期缩短为示例的生命周期。
但是,如果你的应用程序容易受到SSRF的攻击,那么通过允许攻击者也检索你的示例的凭证,同样的优势也可以反过来对你不利。现在你可能会说,这对IMDSv1是正确的,但对IMDSv2不再是正确的。虽然这是真的,但默认情况下IMDSv1总是启用的,因此它仍然是一个常见的普遍问题。
如果你熟悉AWS并且已经在使用IAM角色,你可以使用curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$roleName来了解SSRF在你的应用程序中的致命程度。
如果你对 AWS 不熟悉,可以使用下图中的示例脚本来创建可用于查询元数据终端的 IAM 角色、VPC 和 EC2 示例。不过你得付费,因此请确保在完成后关闭此示例。
创建显示如何利用 SSRF 和元数据终端所需的基础设施(VPC、安全组和 EC2 示例)的脚本
查询元数据终端的截断输出SSRF允许攻击者从你的基础设施外部完全访问这些数据
盲 SSRF(Blind SSRF)
盲 SSRF 是 SSRF 攻击的一个子集。在前面的示例中,客户端已经能够看到对请求的响应。 Blind SSRF 是指你可以执行请求,但看不到响应。乍一看,它似乎是一个相当没有危险的漏洞。但是,仍然可以执行一些有趣的攻击。
一个例子是利用盲 SSRF 来改变内部服务的状态。这方面的一个例子是 Jira 中的一个盲 SSRF 漏洞,它可以被用于在GitLab基础设施中任意发出HTTP POST请求。另一个例子是使用盲 SSRF 从目标网络内部执行端口扫描。这方面的一个例子是 Jira 中的一个盲 SSRF 漏洞,可用于绘制 New Relic 基础设施。
在下图中,你将看到一个应用程序的源代码,其行为类似于 webhook 服务的行为。用户提交 一个URL,服务尝试获取该URL,并将状态代码和漏洞消息返回给用户。
要运行此应用程序,请将下图中的代码保存在名为 ssrf2.go 的文件中,然后输入go run ssrf3.go 以运行应用程序并导航到位于 http://localhost:8080 的应用程序。
可用于映射内部网络的应用程序
要了解如何利用盲 SSRF,请在你的主机上尝试一些终端,看看它们是如何响应的。以下是一些探索步骤:
1、尝试一个没有服务监听的端口。
2、试试端口 22 看看 SSH 是如何响应的。
3、尝试使用 Web 服务器侦听的端口。
4、响应的时机是否提供了任何有用的信息。
SSRF缓解技术
在理想情况下,你的应用程序不需要发出任意请求,或者只需要向一组白名单终端发出请求。在这种情况下,你基本上不必担心 SSRF,因为攻击者无法控制目标终端。
不幸的是,正如我们在前面的例子中看到的,这通常是不可能的。事实上,你可能正在编写一个应用程序,你希望在其中授予用户对终端的控制权,例如 webhook。
SSRF 的缓解措施通常可以分为两大类:你可以在网络层或应用程序层应用控制。
使用防火墙缓解 SSRF
对于SSRF,一种常见的缓解措施是实现关于运行应用程序的主机能够连接到哪些主机的防火墙策略。这通常应用于现有的网络基础设施,其中防火墙位于网络体系结构中的关键位置,或者使用网络设备上的接口 ACL 放置在更靠近主机的位置,或者甚至基于主机的防火墙来限制出站连接。
防火墙可能很脆弱,因为任何应用于主机的防火墙都无法区分应用程序建立的连接与节点或同一节点上其他软件的正常操作规则。防火墙也只能将策略应用于他们看到的流量,因此应用程序可以访问绑定到本地主机或同一网络内其他节点的诊断终端。
基于客户端请求创建出站连接的应用程序也很少见,将来对防火墙策略的更新可能不会考虑到可以创建任意请求的应用程序。
另一个很好的网络层防御是使用类似 Stripe 开发的 Smokescreen 之类的东西。 Smokescreen 是一个 HTTP CONNECT 代理,你可以通过它汇集所有流量,并使用它将 ACL 放置在允许流量的位置。
“Smokescreen 限制它连接到的 URL:它解析请求的每个域名,并确保它是可公开路由的 IP,而不是 Stripe 内部 IP。这可以防止诸如我们自己的webhooks基础设施被用来扫描Stripe内部网络之类的攻击。”
唯一的问题是你的应用程序需要实际支持 HTTP CONNECT 代理并愿意通过它路由你的流量。好消息是,这通常是默认支持的。例如,Go 中的 DefaultTransport 已经做到了这一点,甚至为其他协议添加 HTTP CONNECT 代理支持,就像我们对 SSH 所做的那样。
相互认证
另一种值得讨论的方法是在所有内部服务上使用相互身份验证。回到 webhook 示例,即使攻击者能够控制目标,连接也可能无法通过身份验证与内部资源通信。但是,这种方法不是通用的。如果攻击者可以控制经过身份验证的连接,SSRF 就会重新出现。
使用应用程序控制缓解 SSRF
如果你无法控制网络配置或无法运行 HTTP CONNECT 代理等其他软件,则可以通过检查目标地址是否在阻止范围内来使用应用层控制来缓解 SSRF。
仅仅尝试解析地址、验证地址、然后建立连接是不够的。这很容易受到检查时间和使用时间漏洞的影响,攻击者控制 DNS 服务器并使用短 TTL 在下一次查询时更改目标地址。如果你正在使用应用层控件,请确保使用较低层的挂钩。例如,Andrew Ayer 建议使用带有 Go 拨号器的 Control 回调来执行此操作。
这样你就可以创建安全的拨号程序,可以直接替代也可以应用访问控制的常规拨号程序。看一下下图中的示例,插入式 SafeClient 不仅应用 CIDR 检查,还可以限制 HTTP 重定向等内容。
尝试使用 SafeClient ,并再次尝试利用漏洞。结果还是失败的。
你也可以从命令行尝试此程序。以下是一些可以尝试的示例命令。
使用 Andrew Ayer 技术的更安全的 HTTP 客户端
总结
SSRF 可能是一个难以缓解的漏洞,主要是因为它可能是情境性的。 在某些情况下,你可能希望允许你的客户端连接到内部 IP 地址而不是其他地址。 但是,仔细选择基于网络或基于应用程序的控制可用于有效缓解 SSRF。
如果执行网络安全审计,在审计 Web 应用程序安全性时检查 SSRF 攻击非常重要。