Golem交易的漏洞差点损失1000万美元

  • A+
所属分类:区块链技术

两周前,一位Golem爱好者和GNT持有者报告了一个奇怪的GNT交易bug。 在调查了与交易相关的数据后,我们发现在数字货币交易所的数据交换方式出现了问题。 “哦不,”我们想,“这个bug可能会导致清空数字货币交易所里的整个GNT帐号”!而且可怕的是有相当多的代币存储在那里!
这个bug确实是在数字货币交易所产生的错误,但它也与以太坊智能合约在交易中输入数据的方式,以及Solidity ABI等有关(例如Solidity智能合约的编码方法和解码参数方法)。 所以,它不仅仅适用于GNT,也适用于所有 ERC20 代币以及其他具有转账方法的智能合约。 是的,你没有听错:如果把提款管理方法与GNT管理方法变成一样,那么可能对所有在交易上列出的,和所有基于以太坊的代币都会造成影响。我们们不知道具体事例是不是这样,但很可能是我们猜想的那样。

以太坊智能合约ABI

原始的以太坊智能合约是没有 Method 和 Function。Method 是高级语言(如Solidity)的特征,他们使用智能合约 ABI 来指定智能合约的字节代码将其划分 Method ,以及如何在交易输入数据中编码不同类型的参数。
更多详情请看这里
要使用GNT智能合约的 transfer(address a, uint v) 方法将1 个 GNT 代币转账到地址0xabcabcabcabcabcabcabcabcabcabcabcabcabcabca,需要包括3条数据:
1. 4 bytes 作为方法id:a9059cbb
2. 32 bytes,转账地址(20 bytes),其余用零填满:000000000000000000000000abcabcabcabcabcabcabcabcabcabcabcabcabca
3. 32 bytes 转账代币数量, 1 * 10¹⁸ GNT:00000000000000000000000000000000000000000000000000000de0b6b3a7640000
因此,完整的交易将如下所示:a9059cbb000000000000000000000000abcabcabcabcabcabcabcabcabcabcabcabcabca00
000000000000000000000000000000000000000000000000000de0b6b3a7640000。

交易中输入数据是无限的

这是以太坊虚拟机的更复杂的一个方面,但是完全理解这个问题至关重要。EVM可以使用 CALLDATALOAD 操作码读取任何给定的偏移值的字节。如果交易发起者在交易中未提供偏移值,则EVM 默认设置偏移值为零。同时,合约能够使用 CALLDATASIZE 操作码检查提供的交易 input data 的实际长度。

错误

准备代币转账的服务器假设用户输入20 bytes 的地址,但是实际上没有检查地址的长度。上述转账操作中,用户填写了一个较短长度的无效地址:79735。由于地址参数占用了14.5 bytes(填充零12 bytes + 4.5 bytes 用户输入字节),所以导致数据格式错误。准确地说,交易数据对于以太坊平台来说是很适用的,因为除了每个字节的费用它不关心交易中包含的数据。
GNT智能合约没有执行将代币转账的唯一原因是交易中金额非常高(高于总供应量,也高于相关地址的余额)。用户在使用这样一个短字符串的地址中,地址的所有者真的非常幸运:如果有一些坏运气,用户将会顺便清空所有GNT的地址,并将它们发送到一些随机地址。这时我们意识到这个问题也可以用于攻击,并且问题非常严重。

可能的攻击

您可能已经注意到,允许用户输入较短的转账地址会将“要转账的代币数量”值向左移动,从而使该值更大。 在地址结尾的零处找到一个以太坊地址的私钥也很容易,例如。 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000。因此,该地址所有者可以在服务器接口中输入0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(跳过零)。 然后,攻击者通过服务器转一些代币,把错误地址插入进去。 这实际上会导致一个转账金额偏移 16 bits,即65536倍的转账到攻击者的以太坊帐户!

我们做了什么?

确定可能的攻击后,我们们联系了数字货币交易所,并通知他们有关该错误。这是一个惊人的困难和烦人的过程;我们的CEO Julian 打电话给客服,他的代表不想听,并继续大声说,并不是他的业务错误,拒绝听从任何我们的建议。最后,经过几个小时之后,Alex 设法将我们的建议提交到CEO级别的大佬那里,然后我们的建议就通过了。一旦我们听到关于错误已经修复的确切消息,我们就会去其他数字货币交易所。虽然我们没有理由认为交易所是脆弱易受攻击,但我们也没有理由认为他们很强壮能够抵抗攻击。虽然我们不得不承认我们还没有测试过其他数字货币交易所和其他代币,但是我们意识到如果有人利用这个错误应用在多个数字货币交易所的代币上,造成的后果会让我们感到震惊甚至是害怕:整个以太坊代币经济和其生态系统会受到极其大的打击,甚至倒退回多年以前。

以太坊应该做些什么?

虽然我们认为,以太坊开发人员在教育公众关于以太坊是如何实际工作的方面上很难再加把劲,但我们会建议在以后“Solidity”的版本中增加一些检查功能,例如验证交易输入数据长度是否符合给定智能合约方法的预期数据。

数字货币交易所应该绝对要做的是什么?

1.验证用户输入尽可能严格。 只需检查用户提供的地址的长度,就可以保护用户不受以上攻击。 此外,验证可用以太坊地址校验(见EIP55),如果可以甚至只使用校验的接收地址。 这既增加了安全性又增加了用户友好性。
2.确保交易数据已正确编码。
3.生成的交易数据也可能被解析,所以需要根据给定的用户输入进行检查。

4.检查gas,gas price 和生成交易的目的地址等其他参数是否符合预期值。

原文:https://blog.golemproject.net/how-to-find-10m-by-just-reading-blockchain-6ae9d39fcd95
翻译:MakoShan

weinxin
共识社
用手机扫一扫,加入组织,时刻关注组织动态。
daodaoliang

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: