Skip to content
On this page

S2C10: CREATE2 Double Constraint

1. 问题

需要部署一个合约,其地址必须同时满足两个约束条件(如地址前缀匹配某些字节)。使用 CREATE2 的 salt grinding 找到合适的 salt。

2. 原因

合约使用地址约束作为访问控制 — 只有从特定地址调用的函数才能执行。通过 CREATE2 的确定性部署,攻击者可以"选择"部署地址。

3. 方案

  1. 分析合约中的地址约束条件(哪些字节必须匹配)
  2. 编写攻击合约
  3. 使用 salt grinding 找到满足双约束的 salt
  4. 部署攻击合约到目标地址
  5. 从该地址调用 mintFlag
solidity
// Salt grinding in Foundry
function findSalt() external {
    bytes32 salt = 0;
    while (true) {
        address predicted = address(uint160(uint256(
            keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initCodeHash))
        )));
        if (checkConstraint1(predicted) && checkConstraint2(predicted)) {
            break; // Found!
        }
        salt = bytes32(uint256(salt) + 1);
    }
}

4. 遇到的陷阱

双约束 grinding 时间: 两个约束条件组合后,搜索空间可能很大。需要高效的计算方法。

5. 陷阱的原因

每个额外的字节约束使搜索空间缩小 256 倍。两个约束组合意味着 256^2 = 65536 倍更大搜索空间(最坏情况)。

6. 如何解决

使用 Rust 脚本或优化的 Foundry test 进行 grinding。对于 2-3 字节的约束组合,通常可以在 < 1000 万次迭代内找到。

7. 技术要点

要点说明
CREATE2 地址计算keccak256(0xff + deployer + salt + keccak256(initCode)) 的最后 20 字节
多重约束 grinding组合多个地址匹配条件增加搜索复杂度
initCode hash相同的合约代码产生相同的 hash,变化 initCode(如 constructor 参数)可改变地址

Built with AiAda