导语:在某次红队测试中,我发现了一种在Lastpass中绕过双因素验证(2FA)的方法。
在某次红队测试中,我发现了一种在Lastpass中绕过双因素验证(2FA)的方法。不幸的是,这一发现是在Tavis Ormandy曝光Lastpass远程命令执行漏洞之前,否则会节省我许多时间。但无论如何,2FA是一层额外的安全防护,主要用来保护用户帐户免受那些已经破解了密码的攻击者对你发起攻击。
当你在使用账号密码登录所需要的服务时,往往都会在获得访问权限之前,面临一个挑战——一个每30秒更改一组6位数的临时代码。比如Google验证器、Authy和Toopher这些基于RFC6238和RFC4226的2FA方案,Lastpass也同样支持。
临时代码是基于几个变量生成,包括秘密种子(secret seed)和时间戳。秘密种子能够使其安全和独特,而时间则是使其以30秒的间隔更改。服务器需要与客户端共享秘密种子,以便能够设置和同步代码生成过程。这通常是通过使用你的2FA应用程序扫描的QR码编码种子来完成的。
LastPass 2FA的实现方式
在寻找绕过2FA的方法时,我研究的第一件事是看QR码如何存储,不过后来我却意外发现了生成有效临时代码的秘诀。因此如果我能以某种方式进行窃取,那么我将能够彻底进行登录(因为我已经拥有密码)。
我在测试帐户中启用了Google身份验证器,当我被提示扫描QR码时,我查看了源代码。
正如你所看到的,QR码是一个img标签,其源属性指向:
/google_auth_qr_code.php?iterations=1&passwordhash=TOKEN
我以前研究过Lastpass,并在Blackhat EU做过演讲,因此当看到参数“passwordhash”时我马上就知道这是什么了。 passwordhash是LastPass用于认证的登录哈希,它由用户密码加盐哈希并使用SHA256-PBKDF2保存。Lastpass使用PBKDF2保护保管库与主密码的加密密钥。由于Lastpass不知道你的加密密钥,所以它们应用了一轮PBKDF2,并将其用作登录哈希参数。
存在的问题
这是什么意思呢? Lastpass将2FA秘密种子存储在可以将你的密码导出的URL下了。所以看起来这真的是打破了2FA的真正目的,如上所述,它应该是一种安全防范,用以防范那些已经拥有密码登录的攻击者。但是按这种情况,你试着想想如果自己有一个安全的房子,保存着最宝贵的财物,而门和保险箱拥有同一把锁是个好主意吗?门钥匙如果打开了保险箱怎么办?
虽然我们知道如何获取获取QR码的秘密网址,但它还有一层身份验证的请求。这意味着我们需要进行身份验证才能检索QR码。因为我们还没有认证(我们需要QR码),所以我们又无法检索。看起来这就像是个鸡和鸡蛋谁先存在的问题。
这个时候我们怎么办呢?——事实上我们可以强制受害者向我们提出请求,这被称为跨站点请求伪造(CSRF)漏洞。通常,目标是“状态更改请求”(更新,创建或删除资源的操作),因为同源策略(SOP)是不会让攻击者看到响应的。不幸的是,Lastpass作为纯图像文件是可以提供QR码的。攻击者可以在他的域上设置一个“img”标签,其中“src”属性指向2FA URL。
还有一点值得注意的是,攻击者没有必要潜伏受害者访问他的恶意网站,他们可以使用像Facebook或Gmail这样的受害者信任的站点上的任何XSS来添加有效载荷来窃取QR码并将其发送回他的服务器。
对于永久的2FA设计还有其他后果。如上所述,通过将登录哈希作为URL参数传递来检索QR码,这几乎相当于在URL中传递密码。另外一点就是登录哈希与解密保管库的主密钥不同,不过1轮SHA256-PBKDF2比较特别。
传递URL中的秘密其实是一个非常不好的安全措施,因为URL是由网络服务器记录的。 Lastpass可以保护存储所有用户数据的数据库,但是它们对日志也会应用相同的安全标准,而攻击者通常会针对性的寻找秘密的日志。
URL也在缓存、代理、引用标头甚至浏览器历史记录中被泄漏。
使用CSRF禁用2FA
事实上,写这篇文章的原因是因为我想强调将密码和2FA作为“独立实体”的重要性。但真相是,我发现另一种更直接的方式是来禁用2FA,但在技术上却没啥意思。
真正的长久之计其实是重新生成2FA秘密种子。该功能的实现有3个问题:
重新生成种子不要求你通过要求临时代码来验证设置;
重新生成种子会自动禁用2FA(而不是使其启用但使用新的种子);
再生种子的要求容易受到CSRF漏洞的影响;
所有这些问题的结合使得攻击者有可能禁用受害者的2FA保护。
禁用2FA的请求如下所示:
GET /google_auth_regenerate_key.php HTTP / 1.1 Host:lastpass.com Cookie:PHPSESSID=REDACTED
典型的CSRF是指在没有CSRF令牌的状态改变请求的GET请求,访问攻击者控制站点的受害者可能被迫提出请求并禁用2FA。
LastPass修复方案
Lastpass在报告当天就推出了初步修复方案,目前正在努力确定所有CSRF的脆弱性要求(还有更多),并通过添加CSRF令牌来修复通过CSRF漏洞禁用2FA。
在不安全的2FA设计方面,他们推出了一个初始修复程序来检查Origin标题。这将确保获得QR码的请求只能来自lastpass.com。这是一个很好的立即修复,但不支持旧浏览器不支持Origin标头。
他们还停止使用登录哈希检索QR码,并使用“uidhash”。 uidhash是“uid的SHA256哈希与服务器密码相结合的随机每用户盐(基于用户的uid查找)。我们还在数据库中存储值的哈希值,所以我们可以在X分钟后强制执行该值,并确保用户实际请求释放该信息。”
时间线
02/07/2017:漏洞报告给Lastpass。
02/08/2017:确认漏洞。 CSRF被修复,添加原点检查,密码哈希不再被使用了。
02/10/2017:发放赏金。