智能合约攻击和漏洞百科全书 Attacks----Insufficient gas griefing

不充足的Gas恶意攻击

        可以将 "Insufficient gas griefing" 翻译为 "燃料不足攻击" 或 "燃料不足悲剧"。这个术语指的是攻击者故意发送不够燃料的交易,以引发合约执行失败、交易被回滚或其他不良后果。攻击者利用燃料不足的情况,可能导致合约无法正确执行预期操作,从而达到攻击目的。

        Griefing 是一种经常在视频游戏中执行的攻击类型,其中恶意用户以意想不到的方式玩游戏以打扰其他玩家,也称为拖钓。 这种类型的攻击还用于防止交易按预期执行。

        这种攻击可以在接受数据并在另一个合约的子调用中使用它的合约上进行。 这种方法通常用于多重签名钱包和交易中继器。 如果子调用失败,要么还原整个事务,要么继续执行。

        让我们以一个简单的中继合约为例。 如下所示,中继合约允许某人在无需执行交易的情况下进行交易并签署交易。 通常在用户无法支付与交易相关的 gas 费用时使用。

contract Relayer {
    mapping (bytes => bool) executed;

    function relay(bytes _data) public {
        // replay protection; do not call the same transaction twice
        require(executed[_data] == 0, "Duplicate call");
        executed[_data] = true;
        innerContract.call(bytes4(keccak256("execute(bytes)")), _data);
    }
}

        这段代码实现了一个中继器(relayer),它用于执行其他合约的特定函数。在执行之前,会进行重放保护检查,以确保同一交易不会被重复调用。

        上述代码中的中继合约(Relayer)允许某人在无需执行交易的情况下进行交易并签署交易。通常情况下,这种中继合约的使用场景是当用户无法支付与交易相关的 gas 费用时。

        在以太坊网络中,执行交易需要支付一定数量的 gas 费用,这是为了确保网络的可靠性和安全性。然而,有时用户可能没有足够的以太币来支付所需的 gas 费用,导致无法直接执行交易。

        中继合约的作用是让用户可以通过在中继合约中发送一笔交易并签署它,而无需实际执行该交易。中继合约会接收到用户发送的交易数据,进行重放保护检查,然后将该交易转发给其他合约进行实际执行。这样,用户就能够间接地进行交易,而无需支付与交易相关的 gas 费用。

        换句话说,中继合约充当了一个代理,允许用户委托交易的执行,以解决用户无法支付 gas 费用的问题。这种方式可以为用户提供更多的灵活性和便利性,同时确保交易的有效性和安全性。

        执行交易的用户,即转发者,可以通过使用刚好足够交易执行的 gas 但没有足够的 gas 来使 subcall 成功来有效地审查交易。

        有两种方法可以防止这种情况发生。 第一个解决方案是只允许受信任的用户中继交易。 另一种解决方案是要求转发器提供足够的气体,如下所示。

// contract called by Relayer
contract Executor {
    function execute(bytes _data, uint _gasLimit) {
        require(gasleft() >= _gasLimit);
        ...
    }
}

猜你喜欢

转载自blog.csdn.net/ljh1528207303/article/details/130922842
gas