Home Blockchain Solidity漏洞 外部合约的引用
Post
Cancel

Blockchain Solidity漏洞 外部合约的引用

以太坊作为「全球计算机」的好处之一是能够复用代码,并与已经部署在网络上的合约进行交互。因此,大量合约都引用外部合约,在一般操作中使用外部调用与这些合约进行互动。这些外部消息调用可以用某种不明显的方式掩盖黑客的意图。

坑点分析

在Solidity中,任何地址都可以作为一个合约,尤其是当合约的作者试图隐藏恶意代码时。 让我们举一个例子来说明这一点,请看下面这段基本实现了Rot13密码的代码: image

代码13

这个代码只需要一个字符串,并通过将每个字符转移到右边的第13个位置(包括z),如「a」转换为「n」和「x」转换为「k」。

然后,我们用下面代码对下列合约进行加密: image

代码14

这个合约的问题在于encryptionLibrary地址不是公开或不变的。因此,合约的部署人可以在构造函数中给出一个地址,指向这一合约: image

代码15

这就实现了rot26密码(即每个字符移26个位置),我们还可以将下列合约联系起来: image

代码16

如果在构造函数中给出了其中任何一个合约的地址,则encryptPrivateData ()函数只会生成一个事件,即打印未加密的私有数据。

在这个例子中,虽然构造函数中设置了一个类似库合约,但特权用户(如一个owner)通常可以更改库的合约地址。如果一个联接的合约不包含所调用的函数,则将执行fallback函数。

例如,这行

encryptionLibrary.rot13Encrypt(),

如果encryptionLibrary指定的合约如下: image

代码17

然后会发出一个文本为「Here」的事件。因此,如果用户可以更改库合约,那么,他们原则上可以让用户在不知情的情况下运行任意的代码。

因此,开发者要杜绝使用这样的加密合约,因为在区块链上可以看到智能合约的输入参数。 此外,Rot密码也并不是一个理想的加密技术。

避坑技巧

如上所述,无漏洞合约可以在某些情况下以恶意行为的方式部署。审核员可以公开地核实合约,并使其所有者以恶意方式部署合约,从而导致公开审计的合约具有漏洞或恶意属性。

有许多方法可以防止这些情况发生。

一种方法是,使用new关键字来创建合约。在上面的例子中,构造函数可以写成: image

这样,在部署时就可以创建引用合约的一个实例,而部署者也无法在不修改智能合约的情况下,用其他任何方式替换Rot13encryption合约。

另一个方法是,对已知的外部合约地址,进行硬编码。

一般来说,开发者应该仔细地检查调用外部合约的代码。作为一个开发者,在定义外部合约时,最好是让合约公开(除了在honey pot的情况下),以便使用户能够很容易地检查合约中引用的那些代码。

相反,如果一个合约有一个私有的可变合约地址,那么这可能就是合约被恶意攻击的标志。 如果一个用户能够更改用于调用外部函数的合约地址,那么通过实现一个时间锁或投票机制,使用户能够看到哪些代码正在被更改,或者给参与者一个选择新合约地址的机会。

真实案例:重新入口的蜜罐攻击

最近,一些honey pot(蜜罐攻击)已经被放到了主网上。这些合约试图智取那些试图利用这些合约的以太坊黑客,但他们反过来又让以太币失去了它们期望利用的合约。

举一个使用了上述攻击的例子,其中用构造函数中的恶意合约替换了预期的合约

作者:笔名辉哥 链接:https://www.jianshu.com/p/7d207bdb8b9c 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

This post is licensed under CC BY 4.0 by the author.