500-word postmortem analysis of the latest Ethereum hack

Raúl Kripalani
5 min readJul 21, 2017

--

This attack affected multi-sig wallets based on the Parity wallet.

Update 23rd July 2017: after this post hit the public, I published a second one drilling into the two Ethereum messages that exploited the bug. Read it afterwards to deepen your knowledge of how Ethereum works!

About Parity

Parity is a company created by Dr. Gavin Wood, the author of the Ethereum Yellow Paper that specifies the Ethereum Virtual Machine (EVM).

Gavin announced his departure from the Ethereum team on January 2016. Interestingly, he thanked a bunch of people, except for Vitalik (Reddit thread).

He went on to found Parity, a company that creates Ethereum software.

Amongst their contributions is the exploited multi-sig wallet Solidity smart contract, the target of the attack.

About the timeline of the attack

The attack began on July 18th (UTC+1), when 26,793 ETH were swept from the Edgeless Casino multi-sig wallet.

They were sent to address 0xb3764761e297d6f121e79c32a65829cd1ddb4d32.

Interestingly, thirteen (13) hours elapsed (July 19th UTC+1) before the attackers continued seizing the assets of the Swarm City wallet (44,055 ETH) and the aeternity Blockchain wallet (82,189 ETH), in that order.

I wonder, why the Edgeless Casino team didn’t alert the community immediately? Did they not realise that $6M of their funds had vanished? They had 13 hours to realise and stop further damage to peers.

The transactions executed by the Black Hat hackers. Snapshot taken on July 21st 17:40 UTC+1 from etherscan.io, from the Internal Transactions tab of the black hats’ wallet.

About the bug itself

In Solidity (the programming language for the EVM in which the affected contract was built), function and variables have visibilities.

If not declared explicitly, the default visibility is public:

Public means that the function can be called externally via messages:

The multi-sig wallet snippet developed by Parity had two functions:

  • initWallet
  • initMultiowned

They were only invoked internally by the contract constructor (i.e. when the contract was first deployed), but alas, they were not marked as internal.

What did they do? Their role was to store the Ethereum addresses appointed as owners of the wallet, giving those nominees full access to operate with the wallet (including ETH transfers).

Neither were they decorated with modifiers that checked preconditions (such as being uninitialized).

As a result, the attackers were able to acquire control of the funds in the multi-sig wallets by sending a simple message calling the public initWallet function to override the original owner addresses with their own.

On the left, the original code; on the right, the fix pushed to Github after the attack:

Left: original code exhibiting the vulnerability. Right: vulnerability fix pushed by Gavin Wood following the attack: https://github.com/paritytech/parity/commit/b640df8fbb964da7538eef268dffc125b081a82f#diff-8ea4aa7c2ba715c683bc764337f51585

Here is an example such a message — especifically the one that compromised the aeternity wallet:

About the White Hat intervention

As the attack continued unravelling, Gavin Wood from Parity announced the vulnerability on their Gitter channel:

A White Hat group assembled quickly and determined that the vulnerability could not be patched, and hence the attack could not be stopped.

Remember, contracts are immutable. Once deployed, they cannot be changed.

White Hats leveraged the same bug to to sweep all vulnerable contracts on the blockchain, and drain them before the Black Hat group managed to seize them.

It became a race.

Fortunately, the White Hat group won, and managed to seize the remaining compromised ETH equivalent to over $82M:

At this point, the attack has ceased.

But the Black Hat group has already started moving the stolen ETH around, primarily in quantities of 10,000 ETH:

About responsibility and liability

The code in the Parity Github repository is licensed under GNU v3.0, which means that Parity cannot be held liable, and they do not offer warranty either:

https://github.com/paritytech/parity/blob/master/LICENSE

On the other hand, Parity does make some bold assertions about the quality of their software on their website:

https://parity.io/parity.html
https://parity.io/parity.html

Nevertheless, it is important to stress that this smart contract is simply a snippet produced by the Parity team, made open source.

If the affected ICO-funded projects copied/deployed the snippet without performing a deep-enough audit, the ones to blame are themselves (unless they professionally engaged Parity).

ICO-funded devs, remember: YOU are ultimately responsible for the soundness of the contracts and the safe custody of the money of your investors.

You are raising tens to hundreds of millions of dollars, in some cases with nothing but a nicely written whitepaper, a cool website and a few lines of code on Github.

You should be talented enough to not go around copy-pasting code from the Internet. This is Ethereum, not Wordpress-land.

If you enjoyed this article, please recommend it on Medium (heart it!), and share it on Twitter, LinkedIn, etc.

Feel free to follow me on Twitter for more stuff like this: https://twitter.com/raulvk.

--

--

Raúl Kripalani

🎈 Engineer @ Protocol Labs, working on libp2p. Previously: ConsenSys, Red Hat, FuseSource, Atos, freelance. From Tenerife, Canary Islands, Spain.