"I Learn Blockchain"-XII. Ethereum Security Parity First Security Incident Vulnerability Analysis

tags: Parity  First security breach  150,000 ether  $30 million

12. Ethereum Security's Parity first security incident vulnerability analysis

As of now, there have been two security incidents in the Parity multi-signature wallet, the first occurred on July 19, 2017, involving Parity 1.5 and above, resulting in the theft of approximately $30 million in 150,000 Ether, the second occurrence. On November 07, 2017, about 500,000 Ethereum was locked in the contract and could not be taken out. At that time, it was worth about 150 million US dollars. This article first analyzes the first security vulnerability that occurred on July 19, The next article will analyze the security vulnerability on November 7, 2017.

In summary, the hacker sent two transactions to each vulnerable contract: the first transaction was used to obtain ownership of the multi-signature wallet, and the second transaction was to transfer all funds on the contract.

Available from the official default addressparitytech/parity Check out the code and switch to tag v1.5.x version, or directly from hereProblem code git id 4d08e7b0aec46443bf26547b17d10cb302672835 Enter to view the complete code.

Attack analysis

Step 1: Become the owner of the contract

// enhanced-wallet.sol
// gets called when no other function matches
function() payable {
    // just being sent some cash?
    if (msg.value > 0)
        Deposit(msg.sender, msg.value);
    else if (msg.data.length > 0)
        _walletLibrary.delegatecall(msg.data);
}

By transferring one to this contract addressvalue = 0, msg.data.length > 0To execute_walletLibrary.delegatecallBranch. Because when calling the Ethereum smart contract through json-rpc,toThe parameter is the contract address, and the contract method to be called will be encoded and placed indataParameters, so the code_walletLibrary.delegatecall(msg.data)In theory, any function in the contract can be called unconditionally. In this security incident, a hacker called a function calledinitWalletThe function:

// constructor - just pass on the owner array to the multiowned and
// the limit to daylimit
function initWallet(address[] _owners, uint _required, uint _daylimit) {
    initDaylimit(_daylimit);
    initMultiowned(_owners, _required);
}

Note in the parameter list_owners, Because it is a multi-signature contract, soaddress[]Namely the address array, the original function of this function is to initialize the wallet with the address list of multiple owners, the function will continue to be called to the bottominitMultiownedfunction:

// constructor is given number of sigs required to do protected "onlymanyowners" transactions
// as well as the selection of addresses capable of confirming them.
function initMultiowned(address[] _owners, uint _required) {
    m_numOwners = _owners.length + 1;
    m_owners[1] = uint(msg.sender);
    m_ownerIndex[uint(msg.sender)] = 1;
    for (uint i = 0; i < _owners.length; ++i) {
        m_owners[2 + i] = uint(_owners[i]);
        m_ownerIndex[uint(_owners[i])] = 2 + i;
    }
    m_required = _required;
}

After this step, the owner of the contract is changed, which is equivalent to obtaining the root permission of the Linux system.

Step 2: Transfer money toownerIdentity callexecuteFunction to extract the contract balance to the address of the hacker:

function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 o_hash) {
    // first, take the opportunity to check that we're under the daily limit.
    if ((_data.length == 0 && underLimit(_value)) || m_required == 1) {
        // yes - just execute the call.
        address created;
        if (_to == 0) {
            created = create(_value, _data);
        } else {
            if (!_to.call.value(_value)(_data))
                throw;
        }
        SingleTransact(msg.sender, _value, _to, _data, created);
    } else {
        // determine our operation hash.
        o_hash = sha3(msg.data, block.number);
        // store if it's new
        if (m_txs[o_hash].to == 0 && m_txs[o_hash].value == 0 && m_txs[o_hash].data.length == 0) {
            m_txs[o_hash].to = _to;
            m_txs[o_hash].value = _value;
            m_txs[o_hash].data = _data;
        }
        if (!confirm(o_hash)) {
            ConfirmationNeeded(o_hash, msg.sender, _value, _to, _data);
        }
    }
}

Note that the modifier after the first line of the function is limited toonlyowner, The hacker carried out the above actions just to break through this limitation.

// simple single-sig function modifier.
modifier onlyowner {
    if (isOwner(msg.sender))
        _;
}

Therefore, the key to the problem is that the aboveinitWalletThere is no check to prevent it from being called again after contract initializationinitMultiowned, And the owner of the contract was changed to a hacker.

solution:

Through the above analysis, we can see that the core problem is the function call of unauthorized, then the repair method is rightinitWalletAnd related interface methodsinitDaylimitwithinitMultiownedRedefine access rights:

// throw unless the contract is not yet initialized.
modifier only_uninitialized {
    if (m_numOwners > 0) throw; 
        _;
}

Passed inspectionm_numOwnersThe value of the variable, if it has been initialized, it will be returned directly (in the old version of solidity, an exception is thrown), no further execution is allowedinitWalletOther methods:

// constructor - stores initial daily limit and records the present day's index.
function initDaylimit(uint _limit) only_uninitialized {
    m_dailyLimit = _limit;
    m_lastDay = today();
}
// constructor - just pass on the owner array to the multiowned and
// the limit to daylimit
function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized {
    initDaylimit(_daylimit);
    initMultiowned(_owners, _required);
}
// constructor is given number of sigs required to do protected "onlymanyowners" transactions
// as well as the selection of addresses capable of confirming them.
function initMultiowned(address[] _owners, uint _required) only_uninitialized {
    m_numOwners = _owners.length + 1;
    m_owners[1] = uint(msg.sender);
    m_ownerIndex[uint(msg.sender)] = 1;
    for (uint i = 0; i < _owners.length; ++i) {
        m_owners[2 + i] = uint(_owners[i]);
        m_ownerIndex[uint(_owners[i])] = 2 + i;
    }
    m_required = _required;
}

It can be noticed that the limit modifier flag is added at the end of the first line of each functiononly_uninitializedThis is the principle and solution for the first security incident of Parity multi-signature wallet. The vulnerability occurred on July 19, 2017, resulting in the theft of approximately $30 million in assets. In the next article we analyze Parity's second security incident.

Intelligent Recommendation

How to represent the Spring Security &amp;quot;custom-filter&amp;quot; using Java configuration?

A value-seeking thing seeing outside the network. What is the equivalent Java configuration for the Spring Security tag? I tried http.addFilter( new MyUsernamePasswordAuthenticationFilter() ) where th...

Remember the traceability of a simple security incident analysis

  background An offensive and defensive confrontation exercise organized by a company involved joint operations of multiple security vendors. As a defensive player in a certain department, he con...

Blockchain security-Ethereum short address attack

0x00 Basic knowledge When the EVM virtual machine parses the bytecode of the contract, it relies on the definition of the ABI to identify where each field is located in the bytecode. About ABI, you ca...

Android HTTPS security vulnerability analysis

In development, we will use the HTTPS protocol to communicate with the server, but if there is no comprehensive master of HTTPS, there are many security vulnerabilities in the code writing, in which m...

Network security vulnerability depth analysis

First, a hole background On July 13, 2021, the US Microsoft Threat Intelligence Center released safety announcement [1], and in the article, the hacker used serv-u 0day to attack the very few US milit...

More Recommendation

[Security Vulnerability] Analysis of Apple Forensics

A double fetch vulnerability exists in the mount() system call of the "nfs" filesystem. In theory, Double Fetch is a conditional race vulnerability, which is a data access contest between ke...

Java Security Axis Vulnerability Analysis

0x01 vulnerability reproduction# Vulnerability: Axis = <1.4 Axis1.4 freemarker Download AXIS Pack 1.4 Put Axis in the WebApp directory of Tomcat. Freemarker.jar is placed in the lib directory of Ax...

Introduction and use of Mythril, an Ethereum security analysis tool

1. What is Mythril Mythril is a smart contract security analysis tool officially recommended by Ethereum. It uses compliance execution to detect various security vulnerabilities in smart contracts. It...

The principle and prevention of Ethereum Solidity smart contract security or parameter attack vulnerability

Vulnerability This vulnerability occurs when a third -party contract or application calls smart contracts. When the parameter is passed to a smart contract, the parameter will be encoded according to ...

The principle and solution of Ethereum smart contract security vulnerability in attack vulnerabilities

Vulnerability One of the characteristics of Ethereum smart contract is the code that can call and use other external contracts. These contracts usually operate Ethereum, and often send Ether to variou...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top