ケース別、攻撃の手口
SQLインジェクションの侵入の手口
今回は、SQLインジェクションの侵入の手口を紹介するが、その前に注意がある。本記事は、システムを防御するにはまず敵を知らなければならない、という意図の下に、攻撃手法を紹介する。実際に試す場合、自分の管理下にあるサーバー以外には絶対に行ってはいけない。ほかのサーバーに攻撃を試した場合、「不正アクセス行為の禁止等に関する法律」に抵触する可能性がある。
自分の管理下にあるサーバーでも、予期しないトラブルが発生することを考慮し、破壊しても問題ない環境を用意するか、問題が発生してもすぐに復旧できるような措置を講じてほしい。また、第3回で紹介した防御方法もあわせて確認してほしい。
さて、ここから実際にSQLインジェクションの侵入の手口を紹介する。
まず、会員サイトなどでユーザーID、パスワードを使って認証して、専用ページを表示するような一般的な認証システムを想定する。この場合、事前に用意されているSQL文は以下のようなものだ。
select * from users where id=’$userid’ and password=’$pass’;
$useridの部分に入力したユーザーID、$passの部分にパスワードを入れてデータベースにアクセスするSQL文を完成させる。例えば、ユーザーIDに「abc001」、パスワードに「abc123!”#」を入力した場合、以下のようなSQL文となる。
select * from users where id=’ abc001’ and password=’ abc123!”#’;
データベースに該当する組み合わせのデータが存在すれば、認証が成功する。ここで、ユーザーIDに「' or 1=1 --」を入力したとするとどうだろう。SQL文は、以下のようになる。
select * from users where id=’' or 1=1 --’ and password=’’;
「--」以降はコメントとなり、以下と同意になる。
select * from users where id=’' or 1=1
検索条件は「id=’'」または「1=1」となり、常に条件が成り立つこととなる。つまり、データベースに登録されたユーザーIDとパスワードに関係なく、常に会員専用のページにアクセスできるのだ。
これが認証を迂回(うかい)する最も初歩的な攻撃方法だ。似たような方法で作成者の意図しないSQL文を実行させ、データベースに対して不正な要求を実行し、データベース上の情報を閲覧/改ざんする方法がSQLインジェクションである。
なお、この攻撃は第3回で紹介した「バインド機構」「エスケープ処理」が
対策として有効だ。
攻撃の窓口となる場所は?
SQLインジェクションの脆弱(ぜいじゃく)性を狙った攻撃では、一般的にWebブラウザからWebサーバーに送信するHTTPリクエストメッセージの中にSQLインジェクションに使用する攻撃コードを挿入する。
HTTPリクエストメッセージの中で攻撃を仕掛けることのできる場所は以下の3つだ(図1)。
・HTTPリクエストライン
・HTTPヘッダ
・HTTPメッセージボディー
まず、HTTPリクエストラインに指定するURIパラメタに攻撃を仕掛けられる。例えば「http://≪ホスト名≫/example.cgi?p=1&code=abc」のように、URLの後ろに「?」記号に続けて、指定されているパラメタを改ざんして、攻撃コードを仕掛ける。
また、入力フォームからの入力の場合でもFORMタグのmethod属性にGETが指定されている場合は、HTTPリクエストラインに格納され送信される。入力フォームの値を改ざんすれば、攻撃コードを仕掛けることができる。
HTTPリクエストラインは通常のWebサーバーのログでも攻撃コードの内容を記録することができるため、攻撃内容を検知することはログの監視を行っていれば比較的容易だ。
続いて、HTTPヘッダではフィールドの値を使って攻撃できる。HTTPヘッダには、汎用ヘッダ、リクエストヘッダ、エンティティヘッダ、Cookieなどがあるが、いずれのヘッダもフィールドにある値をWebアプリケーション側で取り出し、SQL文の生成に利用している場合は、SQLインジェクションの攻撃対象になる可能性がある。
例えばWebアプリケーションでCookieの値を取り出し、SQL文の生成に使用する場合、Cookieに攻撃コードを仕掛けることができる。
HTTPサーバーの標準のログ設定では、HTTPヘッダの内容を全て記録していない場合があるので注意が必要だ。
そして、HTTPメッセージボディーに含まれる値をWebアプリケーションが取り出して、SQL文の生成に使用している場合も、攻撃の対象になる可能性がある。
HTTPメッセージボディーは、HTTPリクエストラインよりも大きなサイズのデータをサーバーに送信することができる。例えば、HTTPメッセージボディーを使用して、入力フォームでFORMタグのmethod属性にPOSTが指定する場合や、AjaxなどでWebAPIに対しHTTPメソッドのPOSTを使用してアクセスする場合だ。
HTTPメッセージボディーは大きなデータサイズを取り扱うことができ、開発者にとって利便性が高い反面、HTTPサーバーの標準のログ記録機能では、攻撃コードの内容を記録できないため攻撃者の行動が追跡しにくい。
これらの窓口からの攻撃は、HTTPサーバーの標準のログだけではなく、WAF/IDS/IPSなどによるログ監視が有効である。
続いて、「個人情報や企業の機密情報など、その情報だけで換金できる情報」「システム情報やデータベースを構成する情報などWebサイトを攻撃するための有用な情報」を入手する場合の手法について解説する。