Shikata Ga Nai

Private? There is no such things.

LAB: SQLインジェクションによる隠されたデータの取得

Hello there, ('ω')ノ

このラボでは、商品カテゴリーのフィルタにSQLインジェクションの脆弱性 が存在し、未発売の商品 (released = 0) も取得できることを確認する必要があります。


🛠️ ラボの概要

アプリケーションは、カテゴリーごとの商品一覧を表示する際に、以下のようなSQLクエリを実行しています。

SELECT * FROM products WHERE category = 'Gifts' AND released = 1;

この AND released = 1 によって、未発売の商品(released = 0)は非表示になっています。

しかし、SQLインジェクションを利用して AND released = 1 を無効化すれば、未発売の商品も表示できる ようになります。


🎯 攻撃の手順

1️⃣ Burp Suite を起動し、リクエストをキャプチャ

  1. Burp Suite を開き、Proxy タブを有効にする。
  2. ブラウザを Burpのプロキシを通じて起動 し、ラボのページを開く。
  3. 商品カテゴリーをクリックして、リクエストをキャプチャする。

2️⃣ SQLインジェクションを仕込む

キャプチャしたリクエストの category パラメータを次のように変更する。

category=Gifts' OR 1=1--

すると、SQLクエリは以下のように変わる。

SELECT * FROM products WHERE category = 'Gifts' OR 1=1-- ' AND released = 1;

💡 OR 1=1 は常に となるため、WHERE 句が実質的に無効化され、すべての商品(未発売の商品を含む)が表示される。


3️⃣ 変更したリクエストを送信し、未発売の商品が表示されることを確認

  1. Forward ボタンを押して、変更後のリクエストをサーバーに送信する。
  2. ブラウザでレスポンスを確認し、未発売の商品 が表示されているかをチェックする。

未発売の商品が表示されていれば、ラボクリア!


🔒 防御策(実際のアプリ開発での対策)

このようなSQLインジェクションを防ぐには、以下の対策を行う必要があります。

  1. プリペアドステートメントを使用する(最優先)
    php $stmt = $pdo->prepare("SELECT * FROM products WHERE category = ? AND released = 1"); $stmt->execute([$category]);
  2. ユーザー入力を許可リストで制限する
    php $allowed_categories = ['Gifts', 'Electronics', 'Clothing']; if (!in_array($category, $allowed_categories)) { die("Invalid category"); }
  3. エラーメッセージを表示しない(データベースのエラーメッセージを隠す)
  4. データベースの権限を最小限にするSELECT のみに制限)

✅ まとめ

🎯 攻撃の手順
1. Burp Suite を使ってリクエストをキャプチャ
2. category=Gifts' OR 1=1-- に変更
3. 変更後のリクエストを送信し、未発売の商品が表示されることを確認

💡 ポイント: OR 1=1 によって WHERE 句の制約を無効化することで、通常は非表示のデータも取得可能になる。

このようなSQLインジェクションは、実際のアプリケーションでもよく発生する脆弱性の一つなので、適切な防御策を理解しておくことが重要です!

Best regards, (^^ゞ