题目信息
- 题目名称: 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 |
|---|---|---|---|
| 0x01 | ECRecover | 签名恢复 | 0 |
| 0x02 | SHA256 | SHA256 哈希 | 0 |
| 0x03 | RIPEMD160 | RIPEMD160 哈希 | 0 |
| 0x04 | Identity | 返回输入数据 | 0 |
| 0x05 | ModExp | 模幂运算 | 0 |
关键特性:预编译合约的 code.length == 0,但调用它们会执行内置逻辑!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END















暂无评论内容