Skip to content
On this page

S1C11: Who Can Call Me?

1. 问题

合约只允许从特定的调用者地址调用 mintFlag。需要部署一个合约在特定地址,然后从这个"被允许"的地址发起调用。

2. 原因

合约检查 msg.sender 是否等于某个预计算的地址。该地址由 CREATE2CREATE 的确定性部署决定 — 需要找到合适的 salt 使部署地址匹配要求。

3. 方案

  1. 分析合约中允许的调用者地址的计算方式
  2. 使用 CREATE2 的 salt grinding 技术找到合适的 salt
  3. 部署攻击合约到允许的地址
  4. 从该合约调用 mintFlag
solidity
// 在 Foundry 中 grinding salt
for (uint256 salt = 0; salt < MAX; salt++) {
    address predicted = computeCreate2Address(deployer, salt, initCodeHash);
    if (predicted == targetAddress) {
        // Found it!
        break;
    }
}

4. 遇到的陷阱

Salt grinding 计算量: 如果目标地址约束很强,可能需要 grinding 数百万甚至数十亿个 salt。

5. 陷阱的原因

CREATE2 地址 = keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode))。要匹配特定地址前缀或精确地址,平均需要 2^n 次尝试(n 为约束位数)。

6. 如何解决

使用 Rust 或优化后的 Solidity 脚本进行 salt grinding。Foundry 的 vm.computeCreate2Address 可以辅助预测。如果约束不强(如前几个字节匹配),在合理时间内可以找到。

7. 技术要点

要点说明
CREATE2确定性合约部署,地址由 sender + salt + initCodeHash 决定
Salt grinding暴力搜索 salt 值以获得目标地址
地址约束越精确的地址匹配(更多字节)需要越多计算量

Built with AiAda