今回は「第29回 SQLインジェクションの復習」で紹介したSQLインジェクションツールのsqlmapを紹介します。開発者や運用管理者のセキュリティ意識が向上しない原因の一つは、脆弱性がどのようなリスクを持っているのか理解していないことが原因であることも少なくありません。今回はSQLインジェクションのリスクの一部である自動化された攻撃ツールを紹介します。
sqlmapとは?
sqlmapとはブラインドSQLインジェクション攻撃を実行するツールです。オープンソースで開発され執筆時点の最新版は2010年3月14日にリリースされたバージョン0.8です。
筆者は偶然、最初のリリースからこのツールを知っていたのですが、このツールの進歩には目を見張る物があります。
sqlmapの概要
- 記述言語:Python
- MySQL, Oracle, PostgreSQL, MS SQL Serverをサポートし、DB2、Informix、Sybase、MS Accessを検出可能
- サポートするブラインドSQLインジェション: boolean型、タイミング型[1]
- GET, POST, COOKIE, ユーザエージェントから自動的に脆弱性を検出
- HTTPおよびHTTPSをサポート
- Cookieベース、HTTPベーシック認証、HTTPダイジェスト認証、NTLM認証の認証をサポート
- OSとDBMS両方のフィンガープリティング(名称、バージョンの検出)
- ユーザ権限、パスワードハッシュ、データベース、テーブルなどの一覧抽出
- 任意SQLの実行(UNIONクエリへの自動書き換え)
- 任意ファイルのアップロードとダウンロード
- 任意コマンドの実行とコマンド出力の取得
- シェルコードの実行
- 権限昇格脆弱性の攻撃
- Windowsレジストリへの読み書きおよび削除
- 公式デモ動画
- http://www.youtube.com/profile?gl=JP&user=inquisb
SQLインジェクションでこんな攻撃も可能なのか? と驚いた方も少なくないでしょう。条件さえ整っていれば、ファイルの読み書きや任意コマンドの実行やMetasploit(オープンソース脆弱性攻撃ツール)のシェルコードを実行するなど非常に機能が豊富です。使い方も簡単なので紹介します。
インストール
インストールは非常に簡単です。pythonがインストールされていれば、Pythonスクリプトのアーカイブを展開してsqlmap.pyにパラメータを指定して実行するだけです。
- ダウンロードサイト
- http://sourceforge.net/projects/sqlmap/files/
開発版のsubversionレポジトリも公開されており以下のURIからチェックアウトできます。
ダウンロートと展開またはsvnレポジトリのチェックアウトが終わったら、sqlmap.pyスクリプトがあるディレクトリに移動して
を実行するとヘルプメッセージが表示されます。今回の記事の執筆にはsvnレポジトリの開発版を利用しました。
sqlmapの使い方
コマンドのヘルプメッセージからも分かるようにsqlmapは非常に多くの機能を持っています。ここでは簡単な使い方を紹介します。
脆弱なWebアプリ
sqlmapを使うには脆弱なWebアプリが必要です。MacBookにPostgreSQL One-ClickインストーラでApache, PHP, PostgreSQLがインストールされた環境に脆弱なWebアプリを作りました。
単純にフォームに記入された内容がusersテーブルに保存されているユーザ名とパスワードに一致していれば「ログインしました」と表示するだけの中身がないアプリです。
このアプリは典型的なSQLインジェクションに脆弱なアプリで、どこが脆弱かすぐに分かったと思います。ユーザ入力である$_REQUEST['username']と$_REQUEST['password']がエスケープなしでpg_query関数に渡され実行されています。
このスクリプトは http://localhost:8080/vulnapp/index.php でアクセスできるように設定されています。
vulndbにはusersとおかしな名前のテーブルsadernzytn_cannot_guess_234234234234が定義されています。
sqlmapが自動的にエラーを検出できるようphp.iniをdisplay_errors=on設定しています。
これだけ明らかな脆弱性があると何もしなくてもデータベースの中身は丸見えになります。
sqlmapの実行
sqlmapの基本的な使い方を紹介します。
GETメソッドでパラメータが渡せる場合はURLにパラメータが記載された状態で渡します。
POSTメソッドでパラメータが渡される場合、--methodオプションで明示的にPOSTを指定する必要があります。送信されてデータは--dataオプションで指定します。
ログイン済みのサイトでSQLインジェクションを実行する場合、セッションIDが必要です。あらかじめWebブラウザでログインしてセッションIDを取得し、--cookie "PHPSESSID=XXXXXXXX" のように指定し取得済みのセッションIDを利用します。
基本的なコマンド
--dbs | データベースの一覧 |
--tables | テーブルの一覧 |
-D | テータベースの指定(PostgreSQLではサーチパス) |
-T | テーブルの指定 |
--colums | -Tと一緒に使いテーブル定義を一覧 |
--dump | -Tと一緒に使いテーブルデータをダンプ |
沢山のオプションがあるので基本的なコマンドの使い方だけを紹介します。これだけもSQLインジェクション脆弱性の危険性を理解できると思います。
まとめ
何故SQLインジェクション脆弱性が狙われるのか、sqlmapのようなツールを使ってみれば簡単に理解できると思います。脆弱なサイトではあればデータの改ざんが自由自在に行えます。
アプリケーションによってはテーブルにプレフィックスを付け、同じデータベースを複数のアプリケーションで共有する機能をもっています。この機能を使うとほかのアプリケーションの脆弱性の影響でデータの改ざんや漏洩が発生する可能性があることを理解できます。
データベース(PostgreSQLの場合Schema)やユーザ権限を正しく管理する重要性や必要最小限の権限のデータベースユーザを利用する重要性も理解できたと思います。MySQLの場合、phpMyAdminでグローバル権限としてすべてのテーブルに権限を与えてしまっているケースを散見します。必ず必要最小限の権限を与えるように注意してください。
SQLデータベースのエラーが発生した場合でも通常のエラーと同じ画面(出力)になる場合はsqlmapが思ったように脆弱性を自動検出してくれない場合もあります。少しでも出力に違いがある場合は、sqlmapを多少カスタマイズすれば自動解析が行えるようになります。
WAFもブラインドSQLインジェクション攻撃に対してはかなり効果的に機能するのですが、様々な回避手法も考案されているので安心できません。sqlmapはセッション管理機能も持っており、既に解析済みの情報を取得するためにクエリを繰り返しません。ファイアーウォールなどでリクエスト数を制限することはあまり意味ありません。
脆弱性対策の基本は脆弱性の修正です。基本と原理を正しく理解していれば、SQLインジェクションに対して堅牢なサイトを構築することは難しくありません。うっかりミスがないよう注意してください。