本文整理自Parity亚洲技术总监贾瑶琪先生在万向区块链蜂巢学院直播间进行的Web 3.0训练营公开课。
过去几年,从比特币到以太坊,区块链系统从最初的分布式账本功能,慢慢进化到现在类似于分布式计算机。初期的比特币只能用于在线电子支付或跨境支付,但是现在有了各种各样的智能合约以及链上的运行逻辑,大家可以轻松地在以太坊以及其他区块链平台上进行编程和运算。
如上图,大家可以看到不同的节点目前其实是蕴含对智能合约等其他程序的处理能力。左边的用户可以使用密钥进行数据签名,然后发送交易给节点,节点处理这些交易之后会更新对应的状态生成区块广播给其他节点,其他节点会进行运算和验证然后写入本地的区块链。这样的分布式系统环环相扣,保证了不同国家、地区的用户可以在这台世界计算机上面进行操作和运算。
功能这么强大的分布式计算机听起来很酷,但是从安全角度来看,当一个系统支持的逻辑功能越多,其实它的安全隐患是越多的,这也是为什么比特币系统的安全性相对以太坊要好很多的一个原因。
参见以太坊的重大安全事件,大家可以发现,如果一个区块链平台上的安全问题频频曝出,也会打击大量的开发者以及一些创业公司在平台上部署商业应用的信心。
当我们去看另一个区块链平台EOS,明显可以感觉到对应的安全事件,其实是跟对应的价值关联度更高。不管是链本身还是智能合约层出不穷的安全问题,整体使得大家更加倾向于选择去中心化程度高,以及更加安全的区块链平台去部署自己的商业逻辑。
过去一年有各种各样的DeFi攻击事件,为大量的区块链开发者敲醒了警钟,当上线各种新功能之前一定要做好安全审计,尽量保证自己上线的功能是没有较大的安全问题。
下面我们就来认识一下区块链中常见的攻击类型。
第一类:恶意攻击
(1)重入攻击
2016年的DAO问题以及最近的DeFi问题,都是由类似攻击导致的。攻击者编写了对应的恶意智能合约,调用受害者的合约,同时利用自己的回调函数,循环地调用受害者合约的代码。由于是重复进入受害者合约执行对应的一段代码导致漏洞,所以把它叫做“重入攻击”。
如上图,右边是恶意智能合约,左边是正常的智能合约。正常的智能合约如果按照左边的逻辑,其实应该从上到下进行withdrawBalance,然后以太坊转账,最后更新对应用户的余额。
然而,恶意合约的执行逻辑则是,首先发起Withdrawal的函数,调用withdrawBalance函数,之后左边正常的智能合约会调用对应的withdrawBalance,以太坊转账,当转账一旦完成,由于以太坊本身的特性,就会调用恶意智能合约里面的回调函数,回调函数就会进一步的调用左边的withdrawBalance。
整体来看,按照这个箭头一二三四,形成了一个循环。导致的后果就是恶意合约在发起调用之后,可以一直不断、如此往复地进行转账,把左边智能合约里的余额源源不断地转到攻击者的地址,只要左边智能合约的燃料费是足够的以及还有余额,最终会把所有余额转给对应的攻击者。
这是一个简略的流程图,大家可以看一下实际代码,左边是正常的智能合约,右边是攻击者的智能合约。攻击者智能合约,在右上角进行发起,调用左边withdrawBalance函数,之后调用call.value(),call.value()就触发了恶意智能合约的默认payable的回调函数,默认回调函数会进一步的再触发循环,直至整个左边智能合约所有余额都转给恶意攻击者。
由于重入攻击,The DAO的合约在当时损失了超过6000万美金的ETH。区块链有不可篡改的特性,这样的交易是不能撤回的,因而造成了永久性损失。当时一部分社区成员想修复这样一个漏洞来退回对应损失的以太,但也有一些社区成员不赞同这样的作法,最终导致以太坊分叉,出现了大家熟知的ETC/以太经典。