PR 本記事には広告(Amazonアソシエイト・もしもアフィリエイト・A8.net等)が含まれます。掲載情報の正確性には努めていますが、商品の詳細は必ずリンク先で最新情報をご確認ください。
CTF・セキュリティ学習

【レースコンディション編】タイミングの隙間を突く攻撃と守り方|CTF思考フレームワーク #12

安全に生きたい編集部

📖 この記事はシリーズの一部です

「CTF思考フレームワーク」 Web脆弱性編 #12 / 公開中 10記事 → シリーズ一覧を見る →

レースコンディションって、説明されると「なるほど」だけど実装してる時に忘れがちな脆弱性。「先に小切手を見せて、お金を引き出して、そのあと小切手を破る」みたいな話で、検証と実行の間にスキマがあるとそこを突かれます⏱️

クーポン重複利用、残高マイナス、招待リンク無限利用…レースが絡む脆弱性は地味に金銭被害が大きいです。

難易度:★★★(上級)

同時実行のタイミングを突く攻撃。再現が難しいけど決まると凶悪です⏱️

レースコンディションは「同時に2回送る」だけで残高2倍にできちゃうみたいな話だよ💸

この記事の難易度

難易度:★★★(中級) / 所要:10〜12分 / 前提:CTF思考フレームワーク #11

👀 観察フェーズ:まず何を見る?

まず「在庫減算」「ポイント消費」「クーポン適用」みたいに読み込み→判定→更新の処理を探す!

レースは「チェック → 操作」の間が空くほど刺さりやすい。1回の処理に見えても、内部で複数クエリ・複数サービス呼び出しがあると要注意です。

クーポン適用、出金処理、抽選応募、リワード付与といった「条件チェック→状態変更」が分かれてる箇所はTOCTOUの温床👀

同じリクエストを複数同時送信すると別々の処理として通っちゃうことがあるんだね…😨

🤔 仮説フェーズ:攻撃者は何を考える?

レース系の典型穴は4パターン

攻撃者の仮説。

💰 仮説①:TOCTOU(Time-of-check / Time-of-use)

残高チェックと残高引き落としが非アトミックだと、同時2リクエストで両方とも「残高あり」と判定されて二重出金。

🎟️ 仮説②:1人1回限定の重複利用

「初回限定クーポン」を並列に何十回も送ると、すべて成功して何倍ものポイントが入る。

📨 仮説③:アカウント作成の重複

ユーザー名のユニーク制約チェック→insertの間に同名アカウントを並列作成。DB制約がない実装はやられる。

🔄 仮説④:状態遷移の競合

注文ステータスをpending→paidpending→cancelled同時に叩いて、決済済みなのにキャンセル成立させる。

レースは「同時に投げる」だけのシンプル攻撃。難しいのは検出と再現のほうです。

攻撃ってすごく地味だけど、金額に直結する怖いやつだね…💸

🔬 検証フェーズ:どうやって確かめる?

Burp SuiteのTurbo Intruderやcurl &同時並列リクエストを投げて挙動を観察!

検証ステップ。

HTTP/2のSingle-Packet Attackを使うと数ms以内に同時着弾できるんだね🧪

⚔️ 攻撃フェーズ:実際の手口

レース攻撃の本命はこの3つ

実戦シナリオ。

① 残高・ポイントの二重消費

出金APIを並列で叩いて、残高1万円から3万円分引き出すみたいな攻撃。決済系で実害が大きい。

② 1回限定クーポンの無限利用

初回クーポンや友達紹介報酬を並列でN回適用。すべて成功してアカウントを錬金できる。

③ ユニーク制約の競合突破

メールアドレスのユニーク制約をDBレベルで持っていない実装に同時に登録して、重複アカウント生成→なりすまし。

CTF{single_packet_attack_changes_everything}

近年話題のSingle Packet Attack(HTTP/2で完全同時送信)を使うと、サーバ到達時刻のバラつきがほぼゼロになり、刺さる確率が劇的に上がります。

🛡️ 防御フェーズ:どう守る?

レース対策の3点セットはこれ!🛡️

防御の決定打。

🔐 トランザクション+行ロック

DBでSELECT ... FOR UPDATESERIALIZABLE分離レベルを使い、読み取りから書き込みまでをアトミックに。

🪪 冪等性キー(Idempotency Key)

出金・購入APIにはクライアントが発行する一意キーを必須にし、重複したらサーバ側で同じ結果を返す(StripeやSquareが採用)。

📋 DB制約をアプリに頼らない

ユニーク制約・チェック制約はDBスキーマ側に置く。アプリのコードチェックだけでは並列で必ず破られる。

「並列でも壊れない設計」が本物の堅牢性なんだね💪

🛡️ 今日からできる対策ツール

パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。

PR / 広告

ソースネクスト

※ 上記は他社サービスへのリンクです。購入は各自でご判断ください。

⚠️ よくある落とし穴

よくあるミス。

  1. check_then_actパターン:「if 残高足りる: 残高 -= 額」をトランザクションなしで実装。
  2. アプリ層だけで重複チェックして、DBのUNIQUE制約を省略。
  3. レートリミットだけで安心して、並列実行への防御を考えない。
  4. 「UI上は1回しか押せない」で済ませる(攻撃者はAPI直叩き)。
  5. マイクロサービス間の整合性を結果整合性で済ませて、間に並列攻撃の窓を残す。
  6. 楽観的ロックをversionカラムなしで「実装したつもり」になる。

🧰 ツール早見表

使う道具。

ツール用途ひと言
Turbo Intruder (Burp拡張)並列リクエスト送信Pythonスクリプトで柔軟に
Burp Repeater (Send in parallel)Single Packet AttackHTTP/2でほぼ同時着弾
Race the Web専用レース検出ツール自動化に便利
Wiresharkパケット観察本当に同時送信できてるか確認

🎓 本気で学びたい人へ

Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。

PR / 広告

ササエル

📚 もっと深く学びたい人へ

体系的に攻撃と防御の両面を学びたいなら『ホワイトハッカー入門 第2版』が分かりやすい入口です📚

⚖️ 大事なお約束

必ず守ってね

この記事の手法は、必ず自分の環境か、許可されたCTF・脆弱性報奨金プログラム(HackerOne、Bugcrowd等)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かしましょう🤝

📚 次に読みたい

🧪 自分で検証してみる

「自分でWordPressサイトを立てて、ログイン畫面のセキュリティを実際に試してみたい」なら、まずは安価で高速なConoHa WINGから。初期費用無料で始められます。

PR / 広告

ConoHa WING
記事URLをコピーしました