Appearance
NFT市場への潜入:「タダ乗り」を巡るスリリングな宝探し
想像してみてください: 価値あるNFTが並ぶ真新しいマーケットプレイスが誕生しました。6点の希少なデジタルアートは、それぞれ15 ETHの価値を持ち、購入者を待っています。しかし、驚くべきことに、これらすべてのNFTは簡単に「持ち去る」ことができる重大な脆弱性が発見されました。開発者たちは手詰まりとなり、こう宣言します——これらのNFTを「救出」して彼らの元へ届けた者には、45 ETHの報酬を与えると。
そしてあなたは、その任務を引き受けたブロックチェーン探検家。しかし、手元にあるのはわずか 0.1 ETH。この規模の取引には到底足りません。追加資金の要求も拒否されてしまいました。 「一瞬で無料のETHが手に入れば…!」
これこそが Damn Vulnerable DeFi v4 のチャレンジの一つ——Free Rider です。
脆弱性の核心:FreeRiderRecoveryManager.sol
コードの核心となるのは FreeRiderRecoveryManager.sol です。
■ コンストラクタ
- デプロイ時に 45 ETH(報酬額と同額) の送金が必要 → 初期資金が少ないプレイヤーにとって大きな障壁
■ onERC721Received
NFT受領時に呼び出される関数で、以下のチェックを行います:
msg.sender != address(nft):呼び出し元がNFTコントラクトであることtx.origin != beneficiary:トランザクション発行者が受益者であること_tokenId > 5:対象はID 0〜5のみnft.ownerOf(_tokenId) == address(this):NFTが確実にこのコントラクトに属していること
🚨 脆弱性の本質
最大の問題はここです:
👉 received == 6 のとき、報酬が _data からデコードされたアドレスへ送金される
そして _data は:
👉 safeTransferFrom の引数として自由に指定可能
つまり:
👉 送金先を自分に書き換えられる!
攻撃の鍵:FreeRiderNFTMarketplace.sol
攻撃は以下の2つを組み合わせて成立します:
- NFTマーケットのロジック
- Uniswap V2 のフラッシュローン
攻撃の流れ
1. 下準備
- 手持ちの 0.1 ETH を使い Uniswap V2 に流動性を作成
DamnValuableTokenとWETHのペアを準備
2. フラッシュローン実行
UniswapV2Calleeを使い大量のETHを一時借入- NFT購入+45 ETH支払い分をカバー
3. NFT購入とトリック
buyManyで6つのNFTを購入safeTransferFromに以下を仕込む:recipient→FreeRiderRecoveryManager_data→abi.encode(address(this))
👉 ここが重要:
_dataに「自分のコントラクトアドレス」を埋め込む
4. 脆弱性発動
- NFTが
RecoveryManagerに送られる received == 6条件達成
すると:
👉 報酬 45 ETH が送金される
送金先は:
👉 abi.decode(_data) → 自分のコントラクト!
5. フラッシュローン返済
- 得たETHでローン返済
- 残りが利益
最終結果
- NFT6枚を取得
- 45 ETH 報酬を横取り
- フラッシュローン返済
- 利益確保
重要ポイントまとめ
_dataパラメータの悪用- NFT転送時のコールバックロジック
- フラッシュローンによる資金問題の解決
- tx.origin チェックの不完全性
この「Free Rider」チャレンジは、単なるバグ利用ではありません。
- コントラクト間の相互作用
- コールバックの挙動
- 任意データの危険性
これらを深く理解してこそ攻略できる、極めて洗練された問題です。
わずかな資金でも、ロジックを制すれば市場を制する——それがDeFiの本質です。