OnlyPwner - SEAL 911 - Writeup

OnlyPwner - SEAL 911 - Writeup-魔法少女雪殇
OnlyPwner - SEAL 911 - Writeup
此内容为付费阅读,请付费后查看
300
立即购买
您当前未登录!建议登陆后购买,可保存购买订单
付费阅读

题目信息

  • 题目名称: SEAL 911
  • 作者: 3doc
  • 难度: 高级
  • 类型: EVM 预编译合约利用

题目描述

You barely manage to get off bed as your phone rings. It's THAT ringtone: there's a call for you from the SEAL 911 white hat hotline.

The uber famous Safu DAO just realized that a sophisticated social engineering scheme allowed a hacker to gain access to the private key managing their centralized vault.

The Safu DAO's team incident response procedure is stuck in a bug that was introduced after the last rehearsal. The team shared the leaked key with you, hoping you can recover funds faster than the hacker.

胜利条件

将 Vault 中的所有资金(100 ETH)转移到 safe 地址。


合约分析

Vault.sol 核心代码

contract Vault is IERC165, IERC721, IERC721Errors {
    address public owner;
    address public operator;

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public {
        _requireZero(tokenId);

        if (owner != from) {
            revert ERC721IncorrectOwner(from, tokenId, owner);
        }

        address spender = msg.sender;
        if (spender != owner && spender != operator) {
            revert ERC721InsufficientApproval(spender, tokenId);
        }

        address _owner = owner;      // ① 保存旧 owner
        address _operator = operator; // ② 保存旧 operator

        _changeOwnership(to);         // ③ 改变所有权

        _owner.call{value: address(this).balance}("");  // ④ 资金发给旧 owner!

        bytes4 retval = IERC721TokenReceiver(to).onERC721Received(
            _operator,  // ⑤ 使用旧 operator 作为参数
            from,
            tokenId,
            data
        );
        if (retval != IERC721TokenReceiver.onERC721Received.selector) {
            revert ERC721InvalidReceiver(to);
        }
    }

    function _changeOwnership(address newOwner) internal {
        if (newOwner == address(0) || newOwner.code.length > 0) {  // ⑥ 检查!
            revert ERC721InvalidReceiver(newOwner);
        }
        owner = newOwner;
        operator = newOwner;
    }
}

关键发现

矛盾的安全检查

检查点要求问题
_changeOwnership(to)to.code.length == 0只允许 EOA
onERC721Received(to)返回正确的 selector需要合约行为

这两个条件看似不可能同时满足!


漏洞利用

EVM 预编译合约 (Precompiles)

EVM 内置了一些预编译合约,它们有特殊属性:

地址名称功能code.length
0x01ECRecover签名恢复0
0x02SHA256SHA256 哈希0
0x03RIPEMD160RIPEMD160 哈希0
0x04Identity返回输入数据0
0x05ModExp模幂运算0

关键特性:预编译合约的 code.length == 0,但调用它们会执行内置逻辑!

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容