Skip to content
On this page

S1C11: Who Can Call Me?

1. 問題

コントラクトは特定の呼び出し元アドレスからのみ mintFlag の呼び出しを許可します。特定のアドレスにコントラクトをデプロイし、この「許可された」アドレスから呼び出しを開始する必要があります。

2. 原因

コントラクトは msg.sender が事前計算されたアドレスと等しいかどうかをチェックします。このアドレスは CREATE2 または CREATE の決定論的デプロイによって決定されます — デプロイアドレスが要件に一致するように適切な salt を見つける必要があります。

3. 解法

  1. コントラクト内で許可されている呼び出し元アドレスの計算方法を分析します
  2. CREATE2 の salt grinding 技術を使用して適切な salt を見つけます
  3. 許可されたアドレスに攻撃コントラクトをデプロイします
  4. そのコントラクトから mintFlag を呼び出します
solidity
// Foundry で salt を grinding します
for (uint256 salt = 0; salt < MAX; salt++) {
    address predicted = computeCreate2Address(deployer, salt, initCodeHash);
    if (predicted == targetAddress) {
        // 見つかりました!
        break;
    }
}

4. 遭遇した落とし穴

Salt grinding の計算量: ターゲットアドレスの制約が強い場合、数百万から数十億の salt を grinding する必要があるかもしれません。

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