Fuzzing on-chain contracts with Echidna

By Guillermo Larregay and Elvis Skozdopolj

With the discharge of model 2.1.0 of Echidnaour fuzzing device for Ethereum sensible contracts, we’ve launched new options for direct retrieval of on-chain information, similar to contract code and storage slot values. This information can be utilized to fuzz deployed contracts of their on-chain state or to check how new code integrates with present contracts.

Echidna now has the potential to recreate real-world hacks by fuzzing contract interfaces and on-chain code. On this weblog submit, we’ll exhibit how the 2022 Stax Finance hack was reproduced utilizing solely Echidna to search out and exploit the vulnerability. This incident concerned a lacking validation test within the StaxLPStaking contract, which led to the theft of 321,154 xLP tokens, value roughly $2.3 million on the time of the assault.

Echidna’s “optimization mode” will mechanically uncover transaction sequences that maximize or decrease the result of a customized operate. On this case, we’ll merely ask it to maximise an attacker’s steadiness and let it do the remainder of the work.

Recreating the Stax Finance exploit

To breed the Stax Finance exploit utilizing Echidna, we want:

  • A contract to be fuzzed by Echidna that wraps the goal Stax contract and associated contracts (determine 1)
  • An Echidna configuration file that comprises the block quantity from earlier than the assault occurred and an RPC supplier to get on-chain info (determine 2)

Determine 1 reveals a simplified model of the fuzzing contract contract, and determine 2 reveals the configuration file. You’ll find the total contract and configuration file here.

contract StaxExploit {

    IStaxLP StaxLP = IStaxLP(0xBcB8b7FC9197fEDa75C101fA69d3211b5a30dCD9);
    IStaxLPStaking StaxLPStaking =
        IStaxLPStaking(0xd2869042E12a3506100af1D192b5b04D65137941);

    ...

    constructor() {
        // Utilizing HEVM to set the block.quantity and block.timestamp
        hevm.warp(1665493703);
        hevm.roll(15725066);

        // organising preliminary balances
        ...
    }

    operate getBalance() inner returns (uint256) {
        return StaxLP.balanceOf(tackle(this));
    }

    operate stake(uint256 _amount) public {
        _amount = (_amount % getBalance()) + 1;
        StaxLPStaking.stake(_amount);
    }

    // Different features wrappers ...

    operate migrateStake(
        tackle oldStaking,
        uint256 quantity
    ) public {
        StaxLPStaking.migrateStake(oldStaking, quantity);
    }

    operate migrateWithdraw(
        tackle staker,
        uint256 quantity
    ) public {
        StaxLPStaking.migrateWithdraw(staker, quantity);
    }

    fallback() exterior payable {}

    // The optimization operate
    operate echidna_optimize_extracted_profit() public returns (int256) {
        return (int256(StaxLP.balanceOf(tackle(this))) -
            int256(initialAmount));
    }
}

Determine 1: The attacker contract

Within the fuzzing contract, we added a operate known as echidna_optimize_extracted_profit()permitting Echidna to observe the revenue for the present transaction sequence and establish essentially the most worthwhile one.

testMode: optimization
testLimit: 1000000
corpusDir: corpus-stax
rpcUrl: https://.../
rpcBlock: 15725066

Determine 2: The Echidna configuration file

As proven within the configuration file, we set Echidna to run in optimization mode to maximise the revenue operate.

Subsequent, we ran Echidna on the fuzzing contract utilizing the command in determine 3.

$ echidna ./StaxExploit.sol --contract StaxExploit --config echidna-config.yaml

Determine 3: The command used to execute Echidna

Echidna’s optimizer generates random sequences of operate calls with various arguments, calculating the return worth of the echidna_optimize_extracted_profit() operate for every sequence. On the finish of the run, it discards any pointless or reverting calls from the sequence of transactions, leaving solely these calls that maximize the revenue.

Thus, with our fuzzing contract and the revenue operate, Echidna can swiftly uncover the proper sequence of transactions to breed the hack, while not having prior information of the particular contract exploit.

Determine 4: An Echidna run utilizing the code on this submit

Nitty-gritty particulars

Now that we’ve given a high-level overview of how Echidna can recreate the exploit, let’s dive into some technical particulars for readers occupied with attempting this out on their very own.

To arrange the fuzzing contract, we used Slither’s code generation utilities. This allow us to get the goal contract’s interface and deployment tackle, along with different obligatory interfaces and addresses (e.g., ERC-20 tokens, different contracts, and user-defined information sorts), from Etherscan. We additionally created wrappers for Echidna to name the contract features, and we added our echidna_optimize_extracted_profit() operate.

We took benefit of Echidna’s skill to make use of comm cheat codes for manipulating the execution surroundings. This concerned setting the block quantity and block timestamp to a degree in time simply previous to the precise exploit. To streamline the usage of hevm cheat codeswe used helpers from our properties repository and imported the HEVM.sol helper.

In organising the configuration file, we configured testMode to optimization. We additionally assigned the RPC supplier and block quantity (indicated by rpcUrl and rpcBlock parameters, respectively) for Echidna to fetch the on-chain info. To forestall an indefinite runtime in case Echidna doesn’t discover the exploit, we set an higher restrict of 1 million check runs by way of the testLimit parameter. The ensuing corpus was saved within the corpus-stax listing, as specified within the corpusDir parameter.

Limitations and challenges

Whereas Echidna is a strong device, it’s not with out limitations and challenges:

  1. Echidna may not discover all vulnerabilities. Since fuzz testing can’t assure full protection, it’s essential to reinforce Echidna with different safety testing strategies like static evaluation, formal verification, and even unit testing (e.g., 100% department protection, testing for edge instances, optimistic and destructive checks, and many others.), for a complete evaluation.
  2. Advanced contracts could require extra time. Relying on the complexity of the sensible contract, it’d take Echidna longer to find vulnerabilities.
  3. Fetching contracts and slots from the community may be sluggish. API price limits can hinder the method of buying on-chain info for contracts utilizing quite a few storage slots. There are ongoing discussions on how you can mitigate this subject.
  4. Customization could also be wanted. In sure instances, you might have to tailor Echidna’s configuration or check harnesses to fit your particular use case.

To beat these challenges, observe best practices similar to combining Echidna with different safety testing instruments, totally understanding your sensible contract’s performance, and consulting safety specialists as obligatory.

Echidna improves contract safety

The introduction of recent options in Echidna, similar to on-chain contract retrieval, information fetching, and multicore fuzzing, opens up new methods of bettering the safety of your code in real-world situations. Including fuzz checks into your mission improves the safety of your code by overlaying edge instances that could be neglected by unit or integration checks.

For extra steering on utilizing Echidna, together with detailed documentation and sensible examples, go to our “Building Secure Contracts” website. Should you choose visible studying, take a look at our informative Echidna dwell streams out there on YouTube.

Obtain Echidna at the moment and begin exploring all of its options. Go to our official repository for the newest launch and set up directions. We encourage you to breed this exploit to get aware of the brand new on-chain fuzzing characteristic and to realize insights on the way it may also help make your contracts safer.

Source link

spot_imgspot_img

Subscribe

Related articles

spot_imgspot_img
Alina A, Toronto
Alina A, Torontohttp://alinaa-cybersecurity.com
Alina A, an UofT graduate & Google Certified Cyber Security analyst, currently based in Toronto, Canada. She is passionate for Research and to write about Cyber-security related issues, trends and concerns in an emerging digital world.

LEAVE A REPLY

Please enter your comment!
Please enter your name here