今回のフロムスクラッチ開発ブログでは「CTFのパケット解析から学ぶセキュリティとハッキング」に続いて、SQLインジェクション編の勉強会について書きたいと思います。
※CTFパケット解析編のバックナンバーは、
CTFのパケット解析から学ぶセキュリティとハッキング vol.1 - フロムスクラッチ開発者ブログ
からどうぞ!
1.CTFとは?
CTFとは情報技術に関する問題に対して適切な形で対処することで、「フラグ(Flag)」と呼ばれる得点対象の文字列を取得することによって、得られた得点で勝敗を決める大会です。”Capture The Flag”の頭文字をとってCTFといいます。国内ではSECCON CTFが有名です。(CTFについては、こちらの記事で詳しく触れています。)
2.SQLインジェクションとは?
みなさんは、情報漏洩に対してどれくらい対策を取れていますか?
Amazon GOなど、全てをデータで管理しようとする昨今の社会の流れがあります。より管理が楽になったり、適切なマーケティングができたりと良い面ばかり取り上げられますが、一方で危険性も孕んでいます。
その危険性の一つである情報漏洩、とりわけSQLインジェクションによる情報漏洩に関して、今回は扱います。
2011年ソニーグループが7700万人の個人情報を漏洩させてしまいました。
これは、ソニーグループに対する標的型SQLインジェクション攻撃によるものと考えられています。SQLインジェクション攻撃による情報漏えいの中でも最大規模のものであり、SQLインジェクションへの対策の重要性が広く認識された事件でした。
ソニー・ミュージックの日本語サイトにSQLインジェクション攻撃? - ITmedia NEWS
機密情報、個人情報を少しでも扱うのであれば、SQLインジェクション対策をしておくことがいかに大切かお分かりいただけたのではないでしょうか。
そこで、今回はSQLインジェクションの仕組みを紐解くことで、対策を考えていきたいと思います。
SQLインジェクションとは、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のことです。
一定規模以上のアプリケーションを作るとき、必要になってくるのがデータベースです。いろいろな種類がありますが、現在も多くのWebアプリケーションのバックエンドで使われているのがリレーショナルデータベースです。
そして、アプリケーションのデータ管理を行う際、SQLを中心にプログラミング言語やフレームワークのAPIを用いてリレーショナルデータベースマネジメントシステム(RDBMS)を操作します。そして、このSQL文を書き換えることによって、データ管理者が予期しないデータの漏洩・改ざん・削除などを行うことができます。
では、実際にどのように書き換えを行うのか、SQL構文をおさらいしながら見ていきましょう。
3. データ操作を行う言語、SQL
SQLは、ISO(国際標準化機構)で規格化されたデータベースを管理するソフトウェアを操作・制御することが目的のデータベース言語です。
a.SQLの3つの言語
SQLは、大きく3つの言語に大別することができます。
1つめは、SQL-DDL(Data Definition Language:データ定義言語)です。データベースやテーブルを作成するときに使用します。
2つめは、SQL-DML(Data Management Language:データ操作言語)で、データを操作する時に用いられます。データを操作するとは、例えば、テーブルからデータを取得したり、テーブルにデータを追加したりすることです。
3つめは、SQL-DCL(Data Control Language:データ制御言語)です。データの整合性を保つための機能であるトランザクション制御などに使用します。
それぞれの言語と言語で使われる代表的な構文は以下の通りです。
この中で、SQLインジェクションではSQL-DMLを利用します。
b. メタキャラクタ
「メタキャラクタ」とは、コンピューター言語において、特別な意味を持つ文字のことを指します。単体、もしくは複数の文字が組み合わさって別の意味を持ちます。
SQL文におけるメタキャラクタの代表例は「%(ワイルドカード)」でしょう。
0個以上の任意文字を現し、例えば、以下のSQL文は、名前に「hoge」を含む利用者のみ抽出しています。
SELECT * FROM users WHERE username LIKE '%hoge%';
また、この時の「’(シングルクオート)」もメタキャラクタの一種であり、シングルクオートで挟まれた文字はそのまま文字列として扱われます。
このシングルクオートはSQLインジェクションに多く用いられています。
例えば、以下の2つのSQL文を見てみましょう。
① SELECT * FROM users WHERE username = 'hoge';
② SELECT * FROM users WHERE username = 'hoge' OR 'ab' = 'ab';
①の場合、名前が「hoge」の利用者を抽出します。
一方②の場合、「ab=ab」は常に真であるため、全ての利用者を抽出します。
このような①から②のような書き換えを行うのがSQLインジェクションです。
すなわち、「メタキャラクタ」を用いてSQL文の構造を破壊し、元々あったSQL文を開発者・運営者が意図しないSQL文に改変し、実行させるのがSQLインジェクションの基本原則です。
4. SQLインジェクションでできること
さて、SQLインジェクションで一体何が可能になるのでしょうか。ここでは、主な被害である、「データ窃取」と「データ改ざん・削除」を取り上げます。
a. データ窃取
任意のSQL文を発行することで、データベース中の機密データを抜き出すことができます。
様々な手法がありますが、ここでは表連結を使ったデータの抜き出しを扱います。検索機能を持つSQL文をUNION句を用いて書き換えを行います。
具体的に見ていきましょう。
次のようなアプリケーションを考えます。
/***** 脆弱なコード例 *****/ USE db_users SELECT value FROM data WHERE value LIKE '%{$search}%'; /* データベースへの接続解除(省略) */
例えばURL経由でパラメータ"search"にhogeという文字列を渡したときに取得される表はこのようになるとします。
このとき、テーブルdata以外に次のようなusersというテーブルがあったとします。
パラメータ"search"に
hoge' UNION SELECT id||':'||name||':'||password FROM users --
という文字列を渡すと、次のような表が取得されます。
結果として、別のテーブルのデータを取得できます。
b.データ改ざん・削除
複文を実行できる環境では、DELETE文やUPDATE文を追加することによって、データの改ざんや削除を行うことができます。
例えば、先のデータ窃取で使ったサンプルで、仮に複文が実行可能だとします。パラメータ "search"に';DELETE FROM users;--という文字列を渡すとテーブルusersのデータが削除されます。
仮に、アプリケーションでユーザーのデータが削除されてしまうと、そのユーザーはアクセスできなくなり、非常に困ってしまいます。
さて、SQLインジェクションの基本情報を確認したところで、例を用いてより具体的にSQLインジェクションの行い方をご説明したいと思います。
続編として掲載いたしますので、ご覧いただけましたら幸いです。
本記事は、前述のとおりSQLインジェクションの攻撃方法を理解することによって、実際のセキュアなシステム開発に生かそうとするものです。
実際のSQLインジェクションの実行等においては法律などに抵触しないように気をつけてください。