慢雾安全海贼王:从DApp亡灵军团,细说区块链安全

在2018上海区块链国际周技术开放日上,慢雾安全负责人海贼王分享了《DApp 亡灵军团》,站在攻击者的角度(特指的亡灵军团),经过一个个真实的攻击案例对以太坊、EOS 等区块链生态里 DApp 的安全窘状进行了剖析,并抛出了相关安全深度思考及如何应对。程序员

这张图总结了智能合约攻防的各个方面,分为两大部分:链上攻防和链下攻防。后端

链上攻防浏览器

对于链上攻防,海贼王选取了5个方面来详细剖析,他说到“Talk is cheap. Show me the code.” 并开始展现了源码进行详细解读。安全

  • 溢出

由于没有使用 SaceMath致使的溢出形成金额能够在攻击者构造的数据中被任意控制,从而致使条件判断成立最终攻击者成功攻击了该智能合约。bash

此类问题避免方法:在作数字计算的相关代码处严格使用 SafeMath 进行作算术运算,防止溢出产生。网络

  • 权限控制

此类权限控制属于权限问题中的一种,因为合约开发人员的不专业致使的代理转帐函数中未进行受权判断,从而致使任何人均可以转走别人的钱。并发

此类问题避免方法:找专业的开发人员进行合约开发,同时合约开发人员也须要及时提升本身的开发技能以及专业能力,因为区块链的去中心和Token的特殊性很容易由于一个小的漏洞致使项目方今后身败名裂,因此建议项目上线以前找专业的安全审计团队出职业的审计报告,此类问题慢雾在审计的过程当中必定可以发现并帮助项目方避免这种尴尬的状况。app

  • 条件竞争

此类问题为条件竞争致使的跨合约调用屡次恶意转帐最终攻击者成功完成攻击,在跨合约调用方面一直存在很大的问题,因为开发者的专业技能不够专业或者是合约设计的不合理等问题都会致使此类条件竞争。函数

此类问题避免方法:了解 Solidity 语言自己的函数使用场景以及底层实现,而且在业务逻辑上先扣除须要减去的帐户金额再添加到对应帐户并及时清零中间变量的临时值,避免由于事务的问题致使多入帐致使损失,同时也要了解清楚Solidity中someAddress.call.value()方法 和 someAddress.transfer() 方法还有someAddress.send() 方法的区别。很是不建议使用 someAddress.call.value(),具体缘由请你们必定要本身动手去查一下。区块链

  • 假充值

假充值这类问题是一个系列,好比XRP的假充值和USDT的假充值等,在这里只讲 ERC20 的假充值问题,这种问题是因为合约开发人员的逻辑判断代码不规范致使在以太坊的区块浏览器中能够看到本来一笔失败的转帐状态为Success交易所在进行充值入帐的时候也没有严格进行状态的判断和金额的校验从而致使了此类问题,此类问题杀伤力强,而且一次足以让一个交易所亏损上百万及千万,不管是开发者仍是交易所都须要足够重视假充值的问题。

此类问题避免方法:合约开发中代码判断逻辑的地方使用 require()或者 assert()进行判断,若是条件不知足会直接致使 transfer 的失败同时状态也是 fail ,交易所钱包业务开发人员须要在充值的时候注意严格校验转帐状态是成功仍是失败,同时对充值金额也进行校验,确认真的到帐后此笔交易才算成功。

5. 恶意事件

此处须要说明这里的代码仅仅是咱们编写做为演示使用的,目前暂时没有发现这种真是的攻击行为。因为区块链的数据都记录在链上,恶意记录 event 的事件能够直接修改对应的参数,若是此代码真是存在则上面讲的假充值就真的成了真充值了。

此类问题避免方法:作好 Code Review 和找专业的代码审计。

链下攻防

对于链下攻防,海贼王一样选取了5个方面来详细剖析。

  1. WEB

在以前发生的MyEtherWallet发生的域名劫持事件前,实际上相关的安全机构已经给出了中级风险的提示(以下图),可是它并无对此重视。

终端
对于硬件钱包的安全,也可能存在各类的安全隐患如:是否使用加密芯片,工业设计是否安全,作工是否很简陋不考虑丢失以及意外破损和可否以应对低温高温的状况下正常使用,最终须要考虑你究竟是买了个硬件仍是真正的硬件钱包?

  • 节点

好比以太坊黑色情人节事件,攻击者经过在网络上经过 P2P协议发现新的以太坊全节点,而后构造好攻击脚本作好工程化等待时机对新搭建的全节点进行攻击,因为不少小白用户不懂得如何防护此类攻击因此到目前位置仍是有不少团队不断被盗ETH

详见慢雾的专题页:4294967296.io/eth214/

专题介绍:mp.weixin.qq.com/s/-Yiul1QtS…

慢雾的防护方法:mp.weixin.qq.com/s/Kk2lsoQ16…

  • 矿工

矿工有可能做恶,针对Dapp,进行选择性的打包。针对矿池,针对块代扣攻击等

  • 后端

后端的攻击举例为,USDT 假充值。

攻击步骤为:

1)向交易所钱包构造并发起⽆效(虚假)转帐交易;

2)因为逻辑判断缺陷交易所将⽆效交易⼊帐并计⼊到⽤户在交易所的资⾦帐户;

3)⽤户发起提币;

4)交易所处理⽤户提币将币打到⽤户⾃⼰钱包地址;⽤户⾃⼰充币环节USDT 没有任何损失,提币环节交易所把⾃⼰真实的 USDT 币打给⽤户,形成交易所损失。

这背后的原理是,

USDT 是基于 Bitcoin 区块的 OMNI 协议资产类型,利⽤ Bitcoin 的 OP_RETURN 承载相关交易数据;

Bitcoin 本⾝并不会校验 OP_RETURN 数据的“合法性”,能够是任意数据;

Bitcoin 交易当区块确认数达到 6 的时候,就会被Bitcoin 节点认可;

那么,USDT 的交易在 OMNI 的节点上如何被确认的呢?

int64_t nBalance = 
getMPbalance(sender,property, BALANCE);
复制代码

说明:经过上⾯的代码来看,OMNI内部有⾃⼰的⼀套基于地址的记帐模型,经过地址能够获取地址的余额。

所以,为了不以上问题。

⼀笔 USDT 的交易合法的,要⾄少满⾜如下两个条件:

(1)要经过⽐特币的交易来构造,要符合⽐特币的余额验证(BTC)及交易规则验证

(2)要经过 USDT ⾃⼰的余额(USDT)验证

对于USDT 假充值,当余额不足时会发生什么?

{"amount": "28.59995822", 
"block": 502358, 
  "blockhash": "0000000000000000005968fa48c49d7c4fb2363369d59db82897853fd937c71a", 
  "blocktime": 1514985094, 
  "confirmations": 37854, 
  "divisible": true, 
  "fee": "0.00200000", 
  "flags": null, 
  "invalidreason": "Sender has insufficient balance", 
  "ismine": false, 
  "positioninblock": 301, 
  "propertyid": 31, 
  "propertyname": "TetherUS", 
  "referenceaddress": "1Po1oWkD2LmodfkBYiAktwh76vkF93LKnh", 
  "sendingaddress": "18DmsHjHU6YM2ckFzub4pBneD8QXCXRTLR", 
  "txid": "1b5c80f487d2bf8b69e1bbba2b1979aacb1aca7a094c00bcb9abd85f9af738ea", 
  "type": "Simple Send", 
  "type_int": 0, 
  "valid": false, 
"version": 0 }复制代码

最后,他提醒道,有些黑客很是有心机,在一些百度回答等贴上错误的代码,若是程序员不仔细检查或者对智能合约不熟悉,直接复制粘贴代码,则容易遭受攻击。要如何提高安全呢?首先开发人员拥有安全开发意识,其次仍是要找专业的安全团队作专业的审计。

本文为以太中文网原创发布。

相关文章
相关标签/搜索