Skip to content
On this page

S1C9: Password Protected

1. 問題

コントラクトにはパスワード保護関数があります。mintFlag を呼び出すには正しいパスワードを見つける必要があります。

2. 原因

パスワードはコントラクトの storage に保存されています。ブロックチェーン上のすべてのデータは公開されているため、storage スロットを直接読み取ってパスワードを取得できます。

3. 解法

  1. cast storage を使用してコントラクトの storage スロットを読み取ります
  2. パスワードが保存されているスロットを見つけます
  3. そのパスワードを使用して mintFlag を呼び出します
bash
# storage スロットを読み取ります(異なる slot を試します)
for slot in 0 1 2 3 4 5; do
  cast storage <CHALLENGE> $slot --rpc-url $RPC
done
# 見つけたパスワードを使用します
cast send <CHALLENGE> "mintFlag(string)" "found_password"

4. 遭遇した落とし穴

パスワード形式: パスワードが32バイトを超える場合、複数のスロットに保存される可能性があり、正しく連結する必要があります。

5. 落とし穴の原因

Solidity の string 型は、長さが31バイト以下の場合、単一のスロットに保存されます(短文字列最適化)。それより長い場合、現在のスロットには長さが保存され、データは keccak256(slot) から始まる連続したスロットに保存されます。

6. 解決方法

まずスロット値の最右バイトが長さ×2(短文字列エンコーディング)であるかを確認し、そうでない場合は keccak256(slot) から始まる連続スロットを読み取ります。

7. 技術的ポイント

ポイント説明
ブロックチェーンの透明性すべての storage データは公開されており読み取り可能です
短文字列エンコーディング長さ ≤ 31 バイトはスロットに直接保存され、> 31 バイトは keccak256 アドレッシングを使用します
Storage スロットcast storage または eth_getStorageAt を使用して読み取ります

Built with AiAda