mcpField
B
blockchain-security

blockchain-security

github.com/transilienceaiセキュリティ598585 回インストール13 週間前に更新
リポジトリ

blockchain-security について

blockchain-security は、ブロックチェーン CTF のコントラクトを分析・攻略するためのスキルです。コントラクトの調査、ストレージとアクセス制御の分析、一般的な攻撃手法、勝利条件の確認を扱います。

主な機能

  1. 01コントラクトの逆コンパイルとストレージ解析
  2. 02特権操作とアクセス制御の確認
  3. 03delegatecall と CREATE アドレス攻撃
  4. 04リエントランシーと署名の脆弱性確認
  5. 05攻撃コントラクトのデプロイと勝利条件の検証

活用シーン

  1. 01ソースまたはバイトコードから CTF コントラクトを分析
  2. 02ストレージ配置や delegatecall の攻撃を検証
  3. 03署名、入力検証、アクセス制御の欠陥を確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/transilienceai/communitytools --skill blockchain-security

インストール後、Claude Code で/blockchain-securityを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

reference/
create-address-prediction.md
delegatecall-attacks.md
storage-layout.md

詳細

ブロックチェーンセキュリティ

クイックスタート

  1. コントラクト(ソースコードまたはバイトコード)をダウンロードして逆コンパイルします
  2. ストレージレイアウトをマッピングし、特権操作を特定します
  3. delegatecall、CREATE アドレス予測、リエントランシー、アクセス制御を確認します
  4. web3.py または cast/forge を使ってエクスプロイトコントラクトをデプロイします
  5. 勝利条件(isSolved/flag endpoint)を確認します

ブロックチェーン CTF のチャレンジパターン

# Get connection info
curl http://$HOST:$PORT/connection_info  # -> PrivateKey, Address, TargetAddress, setupAddress
# RPC endpoint
RPC_URL="http://$HOST:$PORT/rpc"
# Win condition: Setup.isSolved() must return true

主な攻撃ベクトル

1. Delegatecall によるストレージ操作

コントラクト A がコントラクト B に delegatecall すると、B のコードは A のストレージを使って実行されます。

  • A のストレージレイアウトを模倣したエクスプロイトコントラクトをデプロイします
  • エクスプロイトコントラクトは delegatecall を通じて A のストレージスロットに書き込みます
  • 重要:ストレージレイアウトは完全に一致している必要があります(同じスロット順序)
  • reference/delegatecall-attacks.md を参照してください
2. CREATE アドレス予測(Nonce 操作)

CREATE によるコントラクトアドレスは決定論的です:keccak256(rlp([sender, nonce]))[12:]

  • どの nonce が目標アドレスを生成するかを見つけるため、総当たりします
  • ダミートランザクション(自身への送金)を送信して nonce を増やします
  • 目標アドレスになる正確な nonce でエクスプロイトコントラクトをデプロイします
  • reference/create-address-prediction.md を参照してください
3. ストレージレイアウトとスロット計算
  • マッピング:keccak256(h(key) || uint256(slot_number))
    • 値型:h(k) = abi.encode(k)(32 バイトになるよう左側をパディングします)
    • String/bytes:h(k) = keccak256(k)
  • eth_getStorageAt を使ってプライベート変数を読み取ります
  • reference/storage-layout.md を参照してください
4. 空配列/長さゼロの入力によるバイパス

関数がユーザー指定の配列をループして項目(署名、承認、投票)を検証する場合、空配列を渡すとループ全体がスキップされます。最小長チェックがなければ、検証をバイパスできます。

  • 確認箇所:require(arr.length >= N) がない for (uint i = 0; i < arr.length; i++)
  • エクスプロイト:関数に [] を渡して、すべての検証をスキップします
5. ECDSA 署名の可鍛性

生の ecrecover は (v, r, s) と (v', r, N-s)(N = secp256k1 の位数、v は 27↔28 に反転)の両方を受け入れます。コントラクトが生のバイト列のハッシュで署名を重複排除している場合、可鍛な形式は異なるハッシュを持ちながら、同じ署名者に復元されます。

  • 確認箇所:s <= N/2 の適用なしで ecrecover が使用されている(OpenZeppelin の ECDSA.sol ではこれが適用されています)
  • エクスプロイト:既知の有効な署名を使い、new_s = N - s を計算して v を反転し、「新しい」署名として送信します
6. よくある脆弱性の種類
脆弱性確認事項
リエントランシー状態更新前の外部呼び出し
アクセス制御onlyOwner / msg.sender チェックの欠如
整数オーバーフローSafeMath を使用していない Solidity < 0.8.0
Delegatecall インジェクションユーザーが制御する delegatecall の宛先
tx.origin による認証msg.sender ではなく tx.origin を使用
SelfdestructETH の強制送金、コントラクト nonce のリセット
弱い乱数エントロピー源としての blockhash/timestamp
空配列によるバイパス最小長チェックのないループ検証
署名の可鍛性s の正規化を行わない生の ecrecover

ツール

# web3.py essentials
from web3 import Web3
w3 = Web3(Web3.HTTPProvider(RPC_URL))
acct = w3.eth.account.from_key(PRIVATE_KEY)

# Read private storage
w3.eth.get_storage_at(contract_addr, slot)

# Deploy contract
from solcx import compile_source, install_solc
install_solc("0.8.13")
compiled = compile_source(source, output_values=["abi", "bin"], solc_version="0.8.13")

# Send raw bytecode deployment
tx = {'data': bytecode, 'gas': 3000000, 'gasPrice': w3.eth.gas_price, 'nonce': nonce, 'chainId': chain_id}
signed = acct.sign_transaction(tx)
w3.eth.send_raw_transaction(signed.raw_transaction)

参考資料

重要なルール

  • 攻撃の前に必ずストレージを読み取ります(プライベート変数はオンチェーンで読み取り可能です)
  • delegatecall を悪用する際は、ストレージレイアウトを正確に模倣します
  • CREATE nonce の総当たりでは、nonce 0~100000 以上を体系的に確認します
  • CTF のインスタンスは短時間で消失することが多いため、速度を上げるために攻撃全体をスクリプト化します

コメント