Webシステムを攻撃する手法としてSQLインジェクションが有名です。 今回は実際に、SQLインジェクションによりパスワードを盗む方法を説明します。
ログインフォームから送信したIDとパスワードが、ソースコード内で以下のような式でクエリされるとします。 また有効なIDが1つ判明しているものとします。ユーザから送信されたIDとパスワードがDB上の値と一致していなければ、クエリの返り値は0件なのでログインすることは出来ません。
select * from user where id='$id' AND pass='$pass'
- 必ずログインする
パスワードに以下の文字列を入力します。
' OR 1 OR '
これは以下のように展開され実行されます。select * from user where id='$id' AND pass='' OR 1 OR ''
OR 1が挿入されることにより無条件でuserがselectされてしまいます。 クエリ結果の最初のユーザをログインユーザとする、と処理されるシステムの場合、この方法によりパスワードを知らなくても必ずログインすることができます。 - パスワードを見つける
上記の方法によりログインそのものは成功しますが、パスワードはまだ判明していません。
挿入する文字列を工夫することで更にパスワードまで判明させることが出来ます。' OR 1 OR '
としていたのを' OR pass like '%' OR '
と書き換えます。 これは以下のように展開されます。select * from user where id='$id' AND pass='' OR pass like '%' OR ''
%は0文字以上の任意の文字列にヒットします。 この状態でもやはりログインに成功します。 次は以下の文字列をパスワードとして送信します。
' OR pass like 'a%' OR '
これはpassの最初の1文字目が'a'であるもののみにヒットします。
この結果はログイン成功 / ログイン失敗に分かれます。
もし指定したIDのuserのpassの1文字目がaであった場合は、ログインに成功します。
もし指定したIDのuserのpassの1文字目がaでなかった場合は、ログインに失敗します。
これをa ~ Z, 0 ~ 9の全ての文字に対して行うことで確実にpassの最初の1文字を特定することが出来ます。
1文字目を特定することが出来れば同じ原理で2文字目以降も特定可能です。
もし全ての文字に対してログインが失敗した場合、次の文字はありません。このようにして、パスワードを盗むことができます。
0 件のコメント :
コメントを投稿