Uber使用Amazon CloudFront CDN的本意本来是为终端用户提供低延迟性和高传输速度,增加用户的客户的体验,但没想到,其子域名http://saostatic.uber.com却被黑客控制以窃取全局共享的Cookie,并间接绕过Uber的单点登录认证。
此外,Uber最近在http://auth.uber.com上部署了单点登录(SSO)系统,该系统基于所有* .http://uber.com子域之间的共享Cookie。
因此,利用子域进行攻击可能会让黑客绕过Uber的整个的基于SSO系统的身份验证过程,从而让他们访问受保护的所有* .http://uber.com子域名,例如http://vault.uber.com,http://partners.uber.com,riders.uber .com等。 Uber为了解决子域控制的漏洞,总共设置了五千美元的奖金。
重新审视单点登录的安全性
一般来说,SSO系统分为以下三种类型:
1.OAuth:安全性主要基于在身份提供者配置的服务提供商的白名单回调URL,以及通过“state”参数进行CSRF保护。缺陷通常是通过打开的重定向链,例如通过OAuth令牌窃取身份验证并绕过Airbnb。
2.SAML & friends:安全性基于在服务和身份提供者之间使用预先交换的加密密钥签名的XML消息。缺陷通常是XML签名会被黑客绕过,例如OneLogin身份验证绕过了以前位于Uber的WordPress网站。
3.子域之间的共享(会话)Cookie:安全性基于所有子域的完整性,在SSO系统发布的共享会话cookie中,任何子域上的任何漏洞都是致命的。因此,缺陷通常是RCE,曝光的调试日志,子域控制和子域上的朋友,例如。通过子域控制验证绕过Ubiquity的单点登录。
专家们认为,虽然OAuth和SAML & friends最近在安全方面有所改善,但还是存在很多问题。而子域之间的共享(会话)Cookie更是一种过时的技术,它被设计成强制要求将SSO系统用作与SSO系统所基于的TLD相同的子域的任何内容。由于SSO系统的安全性是基于子域的完整性,反而给了攻击者大量的攻击机会。
绕过Uber的SSO
Uber曾经使用OAuth作为* .http://uber.com子域名的SSO系统,这可以从@ngalog最近公开披露报告中看出,简而言之,就是CSRF + Open Redirect = Account Takeover。不过最近,黑客们已经根据* .uber.com的子域中的共享会话Cookie更改到SSO了。如果你现在浏览到任何需要身份验证的uber.com子域名时,都将被重定向到auth.uber.com。一旦你登录并访问另一个子域,就可以透过SSO系统auth.uber.com公开地登录,SSO系统在登录一次后会为每个* .uber.com子域发布临时会话cookie。
专家们在这个SSO系统中发现一个漏洞,允许* .http://uber.com上的任何受攻击的子域公开地显示并窃取由http://auth.uber.com为任何 http://uber.com子域名发出的有效会话cookie,不过前提是受害者已经验证过一次SSO。
Uber确实采取了一些对策来防止这种攻击,但是这些措施都被黑客成功地绕过,也就是说任何受到攻击的* .http://uber.com子域可以用于执行相同的攻击。
控制子域名
虽然子域名 http://saostatic.uber.com是通过DNS CNAME指向Amazon Cloudfront CDN的,但主机名却未被注册。这样,黑客就能完全控制这个域名了,并有效地将子域名作为PoC,来托管了一个简单的HTML文件:
如何绕过认证
从下面的Uber SSO登录图中可以看到的,这些使用身份信息的子域会在其结束时立即销毁传入的临时共享会话cookie,以防万一发生信息泄露,例如为其他身份服务商进行的身份验证:
因此,共享会话cookie“_csid” 被窃取只能在发生在上图中的步骤9-12之间,这4个步骤之间的反应时间是非常短的(仅仅够自动浏览器重定向)。虽然利用这么短的时间来发起攻击可能很难,但允许共享会话cookie能在第12步之后在浏览器的cookie存储中进行活动。但问题是,如果受害者已经从Uber(上图中, 12步之后的哪个步骤)登录,当接收到来自auth.uber.com中有效的新生成的共享会话cookie“_csid”的请求时,就被简单地忽略并保持可用。因此,它在浏览器中保持活动状态,直到其Cookie存储被清除。攻击者只需要把上图中的第3步作为步骤13进行重播,并以https://saostatic.uber.com的其他隐藏请求结束窃取会话cookie:
因此,一旦攻击者从Uber得到受害者的“_csid”共享会话cookie,他们就可以在后台浏览器中伪造正常的登录流程,并在步骤9中替换发出的“_csid”cookie的值,从而伪装成受害者登录,以下就是攻击者伪装的Uber SSO登录示意图:
这里的问题是GET服务提供商http://riders.uber.com会在步骤3中添加GET param state=CSRFTOKEN和本地作用域状态cookie,并在步骤11中进行验证。由于目前研究者还无法从受害者的浏览器中获取这些值,而只能利用“_csid”共享会话cookie,所以要做整体的分析就很困难。
另外,攻击者可以从Uber获取正确的CSRFTOKEN值和附带的状态cookie值,使用的方法就是在其末尾启动一个正常的登录方案,例如在后台浏览器中或通过简单的脚本。然后,他们可以在步骤3中将Uber生成的auth.uber.com URL在后台浏览器中定向到受害者的浏览器,以生成并窃取这些值的“_csid”共享会话cookie,并在步骤9中再次将“_csid”共享会话cookie注入到后台的浏览器登录中。这样,受害者就会在其浏览器中有效地为攻击者的伪装登录生成“_csid”临时会话令牌。不过,这仍然允许以以下方式进行删除,从而避免受害者被冒充,不过,研究人员仍然认为受害者已经登录到auth.uber.com并访问受攻击者控制的网页:
PoC
建议大家先观看以下的在PoC演示视频:
视频中假设的是https://saostatic.uber.com是在受害者的浏览器中提供有效的SSL证书,但现实情况并非如此:
1.打开受害者的浏览器并到Uber浏览,在被重定向到Uber之后,请使用受害者的凭证登录,以便你再次在Uber仪表板上查看。
2.在受害者的浏览器中打开第二个浏览器标签,并到https://saostatic.uber.com/prepareuberattack.php浏览。由于视频中只是模拟该域具有有效的SSL证书,所以实践中你要接受可能收到的任何证书警告。页面加载完成后,你将看到一个URL,“Cookie:”字符串和一个“Set-Cookie:”字符串。由于攻击者的网络服务器会收集所有的信息,所以该网络服务器需要伪装成受害者的身份登录,这样一切都被自动窃取了。
3.打开攻击者的浏览器并设置拦截代理工具来拦截请求和响应,到prepareuberattack.php页面输出显示的URL浏览并拦截此请求。现在复制在prepareuberatt.php上显示的“Cookie:…”字符串,并将其粘贴到请求标头中。
4.响应应该是重定向到Uber,这表示验证已经被成功绕过。最后从prepareuberattack.php页面输出中复制所有“Set-Cookie:”行,并将其粘贴到响应中,然后再将其转发到浏览器,这样可以确保被盗的cookies被永久地注入攻击者的浏览器中。
如果你照着以上步骤来操作,也可以伪装成受害者进行登录。
而在实践攻击情形中,攻击者会隐藏在受害者的浏览器中https://saostatic.uber.com/prepareuberattack.php,例如通过iframe。同样,他们可能不会在结果页面上显示URL和所有的Cookie,而是将其存储在服务器端,准备以隐身的方式滥用身份信息。以上的PoC视频演示了攻击者是如何快速有效利用这一招的。 https://saostatic.uber.com/prepareuberattack.php和https://saostatic.uber.com/uberattack.php页面的代码如下,这是专门为PoC编写的:
第一个文件可以托管在任何地方,第二个文件必须托管在被劫持的子域上,因为它读取并窃取了传入的会话cookie。
Uber所采取的预防措施
1.通过将悬垂结构(dangling)的CNAME重新恢复到AWS CloudFront CDN来解决http://saostatic.uber.com的子域名控制。
2.按照以下优先级顺序解决以下任何一种的身份验证绕过:
2.1将SSO系统恢复到OAuth 2,因为这并不会产生像当前的共享会话SSO系统那样所进行大型攻击的副作用。
2.2实施IP地址检查,在http://auth.uber.com上发布共享的“_csid”会话cookie时,存储用户的外部IP地址,并验证向* .uber服务提供商呈现此共享会话cookie的用户。由于 *.http://uber.com具有相同的外部IP地址,所以这样做可以防止如上所述的中继攻击。不过这里还有一个风险,即攻击者可能具有与其受害者相同的外部IP地址,例如在同一个公司网络或无线接入点。
总之,就是Uber通过删除了悬垂结构的CNAME,并实施IP地址检查,来降低基于cookie的SSO系统风险。