Here’s an interesting analysis of the $31 Million Ethereum Hack.

https://medium.freecodecamp.org/a-hacker-stole-31m-of-ether-how-it-happened-and-what-it-means-for-ethereum-9e5dc29e33ce

Ethereum Theft

From a technical standpoint, it appears as though the software developers who built the Parity wallet put in a catch all function that enables unknown functions that are payable, that send you Ether, to default to depositing the Ether.

function() payable {  
  //msg.value is the amount of Ether
  if (msg.value > 0) {
    Deposit(msg.sender, msg.value);  
  }
  throw;
}

In the Parity wallet, the developers took this functionality a step further, and wrote code to state if the value of the Ether is equal to 0 and the length of the msg is greater than zero, then delegate the call to the Wallet.

function() payable {  
  //msg.value is the amount of Ether
  if (msg.value > 0) {
    Deposit(msg.sender, msg.value);
  }
  else if (msg.data.length > 0) {
    //if the msg data has data and msg.value is equal to 0, then delegate 
    //the call to the Wallet Library's version of this function.
    _walletLibrary.delegatecall(msg.data);
  }
}

So what happened?

The thieves understood the vulnerability vector. They invoked the catch all function with the initWallet function. This call was not implemented in the contract, but was implemented in the wallet.

The initWallet function looks like the following:

function initWallet(address[] _owners, uint _required, uint _daylimit) {  
  initDaylimit(_daylimit);
  initMultiowned(_owners, _required);
}

The key piece here is the _owners. They passed in the address of the owners to the wallet. In effect, the thieves initialized the wallet so they became the owners. They drained the tokens from the wallet, and said bye bye.