返回所有文章
发布于 · 作者 Renaud Deraison

那张钓鱼页面就是真页面

一款名为 Bluekit 的工具包不再去伪造登录界面。它从攻击者掌控的浏览器里把真正的那张登录页面流式传给你,在你登录的那一刻劫走你的会话,并绕过 MFA。再敏锐的辨假眼力都拦不住它,而一把通行密钥却能——这正是 Bromure 让一个配置文件只共享你 Mac 上的通行密钥的原因。

二十年来,战胜钓鱼意味着学会识破伪造。而浏览器中间人(browser-in-the-middle) 让你无从识破。它把真正的登录页面摆在你面前,在你眼皮底下窃走你正在进行的会话。 能拦住它的,是一种你无法照抄下来的凭据。

你收到一条消息:一份共享文档、一次被标记的登录、一张发票。你点了进去。一个 Microsoft 登录页面打开了,而且它是真的——字体没错、logo 没错、在输入框之间用 Tab 切换时的那个小动画也没错,还有那个让你手机震动的、货真价实的多因素验证提示。你批准了它。 你登进去了。一切都不觉得有什么不对,因为几乎没有什么不对。你输入信息的那张页面, 就是 Microsoft 的登录页面。只不过,与它对话的人不是你。

六月下旬,Netcraft 的 Harry Everett 记录下了一款名为 Bluekit 的钓鱼工具包完成了这一跳跃,BleepingComputer 也在同一周对它做了 报道。 Bluekit 以服务的形式出售:一套托管式的钓鱼工具包,自带 Outlook、Gmail、iCloud、 GitHub 以及一两款加密货币钱包的模板,还内置了一个帮你撰写诱饵邮件的助手。它的新花招 有一个名字——自从一位名叫 mr.d0x 的研究者在 2022 年描述它以来,这个名字就一直在流传: browser-in-the-middle。

真页面,流式传到你眼前。

老派的钓鱼会造一个赝品。有人克隆登录页面,把它托管在一个外观相似的域名上,指望你不去看 地址栏。防御也是围着这一点长起来的:识破伪造,抓住 URL 里的拼写破绽。

接下来登场的是像 Evilginx 这样的反向代理工具包。它不克隆页面。它坐在连接的中间—— 一个「中间人对手」(adversary in the middle)——把你的流量原样转发给真实站点,并在流量 经过时顺手刮走会话 cookie。(这个 cookie 是站点在你登录之后交给浏览器的一个小令牌, 有了它,站点就不必每点一下都问你要密码。)窃走它就能击败大多数多因素登录,因为攻击者 拿走的是一次已完成登录的凭证,而不是密码。

browser-in-the-middle 更诡异,某种意义上也更简单。攻击者在自己的服务器上跑一个真正的 浏览器,把它指向那张货真价实的登录页面。一个名为 rrweb 的开源库——本是为回放用户会话 而生——把那张实时页面序列化,再通过 WebSocket(一条在你的浏览器与他们的浏览器之间持续 存在的双向通道)流式传给你。你的浏览器渲染出真页面的结构,仿佛是你自己加载了它。你看到 的不是截图,也不是录像。你是在远程操控一个置身于真正店铺里的浏览器,你的击键、你的鼠标、 你的多因素验证批准,都被回传给它。当登录完成时,它是在他们的浏览器里完成的,由他们的 服务器铸出会话令牌。从第一秒起,你的会话就归他们所有。

攻击者基础设施攻击者掌控的浏览器一个真实的无头浏览器真正的登录页面真实站点 · 真实证书你的屏幕login-update.example (攻击者主机)渲染出真页面原生 DOM,不是截图看起来完美,因为它本就是真的rrweb DOM 流 · WebSocket击键 + MFA,回传会话最终落在哪里会话令牌是在攻击者的浏览器里、攻击者的机器上铸出的。从第一秒起,你的会话就归他们所有,而你点下的多因素验证批准改变不了这一点。
browser-in-the-middle。攻击者自己的浏览器已经登入真实站点。一个名为 rrweb 的库通过 WebSocket 把那张真页面的实时结构流式传给你的浏览器,而你的击键和多因素验证批准则反方向回传过去。你验证的是攻击者的会话,而不是你自己的,于是会话令牌是在他们的机器上生成的。多因素验证批准改变不了这一点。来源:Netcraft。

何苦费这番周折?因为它的说服力,是克隆永远做不到的。这里没有一张可能露馅的假页面。 而且,由于攻击者用的是同一个前后一致的浏览器去和真实站点对话,这次登录不会触发那种 「指纹不匹配」的警报(也就是你的设备与代理之间那些细微的不一致)——正是这种警报有时会 让反向代理工具包露出马脚。Netcraft 在仅仅一周之内就数出了大约七十个全新的 Bluekit 主机名。这是一个产品才有的产出。

拦不住它的东西。

先说坏消息,因为坏消息很多。

多因素认证,以它常见的那几种形式,拦不住这件事。一次性验证码和一次推送批准证明的是 同一件事——此刻正在发生一次登录——而这次攻击恰恰需要这次登录发生,因为登录的人就是 攻击者。证明由你来做。会话由他们留下。

更新一些的会话加固手段,帮助也比你期望的要小。Netcraft 指出,「设备绑定会话凭据」 (Device Bound Session Credentials,一种把会话 cookie 绑定到它所签发的那台设备上的方案) 「无法防御 Browser-in-the-Middle,尽管它们确实能对 Adversary-in-the-Middle 提供一些保护」。 会话的生命,从一开始就诞生在攻击者的设备上,所以把它绑定到那台设备,保护的是攻击者, 而不是你。任何在登录之后才加挂上去的东西,都来得太晚,因为到那时候,攻击者已经名正言顺地 握着会话了。

隔离也拦不住它,这一点值得直说。一个把每个标签页都跑在用完即弃的虚拟机里的浏览器—— 就像我们的那样——能够遏制一张页面对你的电脑所能做的事。而 browser-in-the-middle 对你的电脑什么也不做。它只是借用你的双手完成一次登录,再把成果留在一台你永远看不到的 服务器上。你大可以在关掉标签页的那一刻把你自己的会话扔掉。但真正要紧的那一份副本, 从来就不在你这边,扔无可扔。用完即弃能防御一长串攻击,而 browser-in-the-middle 不在 那串名单上。

能拦住它的东西。

再好的假页面检测器在这里也帮不上忙,因为根本没有假页面。真正的解法,是一种攻击者无法 照抄下来的凭据。

密码和一次性验证码有一个共同的致命属性:它们都是字符串。你把一串字符敲进一张流式传来的 页面,线缆把它带走,另一端的浏览器再把它重放出来。这就是整门生意的全部模式。

通行密钥(passkey)是一把私钥,它住在你的设备上,永不离开。所谓登录,是在你用 Touch ID 批准之后,由你的 Mac 对一个一次性挑战进行签名,而它交回的那个签名,被绑定到你当初为之 创建通行密钥的那个确切网站上。由此引出两个后果,而它们都能破掉 browser-in-the-middle。

第一,没有东西可敲,也就没有东西可回传。这个秘密从不出现在页面里,从不穿过 WebSocket, 也从不待在某个表单字段里等着 rrweb 把它流式回传。攻击者的浏览器尽可以随意索取;而签名 发生在你 Mac 里的一块芯片上,攻击者的服务器够不着那里。

第二,你真实银行的那把通行密钥,是注册在你真实银行的域名下的。当攻击者的主机把页面摆到 你面前时,你的 Mac 会去找一把在那里并不存在的通行密钥,于是什么也提供不了。那本该一触 即成的登录,没有发生。那一份沉默——始终没有弹出的自动填充、不在列表里的那把通行密钥—— 正是从前那条假地址栏会给你、而如今再也给不了的警告。

密码是一串字符你把它敲进流式页面密码,然后是一次性验证码穿过 WebSocket被攻击者的浏览器重放字符串总能被重放攻击者握有一条有效会话MFA 也照过秘密离开了你的手。通行密钥是一把钥匙在 Mac 上签名,藏于 Touch ID 之后私钥永不离开设备绑定到真实域名在攻击者主机上:无匹配无可敲 · 无可供登录无法完成rrweb 没有东西可回传秘密从未离开你的 Mac。
为什么通行密钥能破掉这次攻击。左侧:密码(以及随后那串一次性验证码)是一串字符。你把它敲进那张流式传来的真页面,它穿过线缆,攻击者再把它重放出来,铸出一条会话。右侧:通行密钥是一把钥匙。你的 Mac 在 Touch ID 背后为它签名,把它绑定到真实站点的域名上,并且绝不让它离开设备——所以在攻击者的主机上,没有东西可敲,也没有东西可提供,登录无法完成。

把你 Mac 上的凭据借出去的两种方式。

浏览器的设计在这里很关键,因为通行密钥只有抵达你登录的那个地方,才能保护你。

Bromure 把每一次浏览会话都跑在你 Mac 上一台用完即弃的 Linux 虚拟机里——一台独立的小电脑, 在你关掉窗口时被它抹掉。这能很好地遏制怀有恶意的页面,但也带来一个显而易见的问题:如果 浏览器住在一台用完即弃的机器里,那你保存的那些登录信息从哪儿来?Bromure 让你按配置文件 去选择,并且特意把这个选择拆成了两个开关。

使用 macOS 密码

宽松的便利选项。会话会从你 Mac 上保存的密码和 iCloud 钥匙串里自动填充用户名和密码, 而 Chromium 自带的密码库则被关停。它依然是域名绑定的,所以不会往攻击者的主机里自动 填充。但密码终究是一串字符,一个铁了心的人完全可以亲手把它敲进去。便利,但边缘是软的。

使用 macOS 通行密钥

收窄的、抗钓鱼的选项。会话用你 Mac 上保管的通行密钥来登录,而 Touch ID 或你的密码会 为每一次请求把关。你可以在不开启完整密码共享的情况下打开它:只共享通行密钥。没有东西 可敲,没有东西可回传,在错误的域名上也没有东西可提供。这个开关,直接把 browser-in-the-middle 从桌面上拿掉了。

把它们拆开,正是关键所在。把你的整个钥匙串共享进一次会话,是那个便利的默认选项;而 共享通行密钥,才是对本文这种攻击免疫的那个选项。「仅通行密钥」有自己专属的开关,所以那个 抗钓鱼的选择只需你拨一下开关,而不是上一个安全项目。你可以让一个配置文件只有唯一一种验证 方式——那种无法从你屏幕上被流式传走的方式。

这一招解决不了的东西。

一个开关不是力场,它的边界很重要。

最大的那一条值得再说一遍。如果你通过一张 browser-in-the-middle 页面用密码登录——哪怕后面 还跟着一次性验证码或一次推送——攻击者也能拿到一条可用的会话,而用完即弃的虚拟机也好、 聪明的浏览器也罢,都没法把它夺回来。仅通行密钥共享保护的,是你使用通行密钥的那些登录, 仅此而已。仍然有大量站点不提供通行密钥,对它们而言,那条老建议就是唯一的建议:不要去点 消息里的登录链接,自己打开那个站点。

检测有帮助,Bromure 也在用它:过滤式 DNS 会拦掉已知的恶意域名,一个 AI 钓鱼检查会在你 动手之前给页面的 URL 和表单结构打分。两者都能收窄概率。但两者都不是保证,而 browser-in-the-middle 的设计本就是为了让检测更难。一周七十个全新主机名,跑赢了大多数拦截 名单;而内容扫描器,也找不到一张可供标记的假页面。检测能逮住粗心的攻击者。抗钓鱼的凭据, 能逮住谨慎的那一个。

还有最平凡不过的那条边界:人是可以被说动去做很多事的。如果一封令人信服的消息把你领到一个 没有通行密钥的站点,而你敲进了一串在别处重复用过的密码,那么从头到尾,没有任何浏览器设置 参与过这个回合。仅通行密钥共享并不能让你刀枪不入。但对那些最要紧的登录——你的邮箱、你的 代码托管、你的身份提供方——它拿掉了攻击者所图谋的那串字符,留下一把他们够不着的钥匙。

假地址栏正在退场。

我们重复了二十年的那套建议(检查 URL、找那把小锁、怀疑页面),都假设攻击者必须伪造点 什么。而 browser-in-the-middle 什么也不伪造。它把货真价实的那件东西递到你手上,自己则站在 它背后,张着口袋等着。

诚实的结论是:一个安全优先的浏览器并不能让你对这件事免疫,而我们宁愿直说,也不愿假装。 答案,从你的眼睛挪到了你的凭据上。面对一张你无法与真页面区分开的页面,经得起时间考验的 防御,是用一种你无法照抄下来的东西去登录:一把通行密钥,在你的 Mac 上签名,绑定到真实 域名,在攻击者的域名上永不被提供。Bromure 所扮演的那一份角色,很小,也很具体。它让这件 事成为轻松的默认选项——办法就是让一个配置文件只共享通行密钥、别的一概不享。安装它, 为那些你输不起的账户打开「仅通行密钥」,然后就让下一张看上去完美无缺的登录页面,向你索取 一个你再也不必交出的秘密吧。