Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Analysis Server and Reporting Services (2005)
 search in all tables and fields for SQL Injection

Author  Topic 

Mindjogger
Starting Member

9 Posts

Posted - 2008-08-20 : 07:50:17
Hello forum,

we have had a attack to our web and sql server by SQL injection.

Now I have closed the security leak and removed the mailious code. Thats my opinion but not Googles.

So I would like to look in each table and each fields for some keywords (.ru or SCRIPT)

How can I do so wothout doing it table by table and field by field?

Is there a way to say something like:
get all tables - for each table get fields - for each field look for like xxxxx- generate a list or report?

I am realy in trouble regarding this and any help would be high appreciated.

Thank you.

B.S.

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2008-08-20 : 08:24:23
Hi MindJogger,

I recently had a request to find any html elements in any table across multiple databases. I ended up implementing a regular expression function with a cursor. Probably not the most efficient way in the world but it worked for me. End result is in XML RAW format but you could change that to anything required.

You should be able to use any regular expression.

Don't just blindly run this! Have a look first.


USE MASTER
GO

/* Regular Expression Function
**
** uses call to vbscript.RegExp
**
** Charlie (22/Jul/2008)
*/

IF OBJECT_Id('dbo.fn_regex_CS') IS NOT NULL DROP FUNCTION dbo.fn_regex_CS
GO

CREATE FUNCTION dbo.fn_regex_CS(
@pattern VARCHAR(255)
, @matchstring TEXT
)
RETURNS INT

AS BEGIN
DECLARE @obj INT SET @obj = -1
DECLARE @res INT SET @res = -1
DECLARE @match BIT SET @match = 0

-- Make the @res Object.
EXEC @res = sp_OACreate 'VBScript.RegExp', @obj OUT
IF (@res <> 0) RETURN -1

-- Assign the Pattern to it.
EXEC @res = sp_OASetProperty @obj, 'Pattern', @pattern
IF (@res <> 0) RETURN -2

-- Set to ignore Case
EXEC @res = sp_OASetProperty @obj, 'IgnoreCase', 1
IF (@res <> 0) RETURN -3

-- Execute the regular expression
EXEC @res = sp_OAMethod @obj, 'Test',@match OUT, @matchstring
IF (@res <> 0) RETURN -4

-- Cleanup the object
EXEC @res = sp_OADestroy @obj

-- Return the results
RETURN @match
END
GO


/* Search across All Text columns for a pattern
**
** Charlie (21/Jul/2008), Modified (22/Jul/2008)
*/

-- ==== Configuration =========================================================

DECLARE @searchString NVARCHAR(255) SET @searchString = '<[^>]*?(>|$)'
DECLARE @databaseMask NVARCHAR(255) SET @databaseMask = '<YOUR_DATABASE_NAME_HERE>'
DECLARE @debug BIT SET @debug = 0
DECLARE @loggingLevel INT SET @loggingLevel = 0

-- ==== ============= =========================================================

SET NOCOUNT ON
IF object_Id('tempDb..#found') IS NOT NULL DROP TABLE #found
IF object_Id('tempDb..#searchList') IS NOT NULL DROP TABLE #searchList

-- Storage Objects and Variables
CREATE TABLE #found (
[databaseName] NVARCHAR(255)
, [tableName] NVARCHAR(255)
, [columnName] NVARCHAR(255)
, [Id] NVARCHAR(255)
, [value] TEXT
)

CREATE TABLE #searchList (
[TABLE_CATALOG] NVARCHAR(255)
, [TABLE_SCHEMA] NVARCHAR(255)
, [TABLE_NAME] NVARCHAR(255)
, [COLUMN_NAME] NVARCHAR(255)
, [COLLATION_NAME] NVARCHAR(255)
, [DATA_TYPE] NVARCHAR(255)
, [ID_FIELD] BIT DEFAULT 0
)

DECLARE @sql NVARCHAR(4000)
DECLARE @database NVARCHAR(255)
DECLARE @tableName NVARCHAR(255)
DECLARE @columnName NVARCHAR(255)
DECLARE @schema NVARCHAR(255)
DECLARE @dataType NVARCHAR(255)
DECLARE @collation NVARCHAR(255)
DECLARE @idField BIT
DECLARE @msgText VARCHAR(300)
DECLARE @now DATETIME

-- This goes through each database and builds the searchlist table
DECLARE databaseCursor CURSOR FOR
SELECT
[name]
FROM
[master].[dbo].[sysDatabases]
WHERE
[name] LIKE @databaseMask

OPEN databaseCursor
FETCH NEXT FROM databaseCursor INTO @database

WHILE ( @@FETCH_STATUS = 0 ) BEGIN

SET @sql = N'
INSERT INTO #searchList (
[TABLE_CATALOG]
, [TABLE_SCHEMA]
, [TABLE_NAME]
, [COLUMN_NAME]
, [COLLATION_NAME]
, [DATA_TYPE]
)
SELECT
''['' + [TABLE_CATALOG] + '']''
, ''['' + [TABLE_SCHEMA] + '']''
, ''['' + [TABLE_NAME] + '']''
, ''['' + [COLUMN_NAME] + '']''
, [COLLATION_NAME]
, [DATA_TYPE]
FROM
' + @database + '.information_schema.columns
WHERE
[DATA_TYPE] IN (
''VARCHAR''
, ''TEXT''
, ''CHAR''
, ''NVARCHAR''
, ''NCHAR''
, ''NTEXT''

UPDATE sl
SET
[ID_FIELD] = 1
FROM
#searchList sl
JOIN ' + @database + '.information_schema.columns isc ON
''['' + isc.[TABLE_NAME] + '']'' = sl.[TABLE_NAME]
AND isc.[COLUMN_NAME] = ''Id'''

IF @debug = 1 PRINT @sql
EXEC (@sql)

FETCH NEXT FROM databaseCursor INTO @database
END
CLOSE databaseCursor
DEALLOCATE databaseCursor

-- Now have to search through the list. This will take a while...
DECLARE searchCursor CURSOR LOCAL READ_ONLY FOR
SELECT
[TABLE_CATALOG]
, [TABLE_SCHEMA]
, [TABLE_NAME]
, [COLUMN_NAME]
, [DATA_TYPE]
, [COLLATION_NAME]
, [ID_FIELD]
FROM
#searchList
ORDER BY
[TABLE_CATALOG]
, [TABLE_NAME]
, [COLUMN_NAME]

OPEN searchCursor

FETCH NEXT FROM searchCursor INTO
@database
, @schema
, @tableName
, @columnName
, @dataType
, @collation
, @IdField

WHILE ( @@FETCH_STATUS = 0 ) BEGIN

IF @loggingLevel > 1 BEGIN
SET @now = GETDATE()
SET @msgText =
CONVERT(CHAR(11), @now, 106) + ' @ '
+ CONVERT(CHAR(8), @now, 108)
+ ' - Checking.... '
+ @database +
'.'
+ @schema
+
'.'
+ @tableName
+ '.'
+ @columnName

RAISERROR(@msgText, 0 , 1) WITH NOWAIT
END

SET @sql = N'
INSERT INTO #found (
[databaseName]
, [tableName]
, [columnName]
, [Id]
, [value]
)
SELECT
@database
, @tableName
, @columnName
, ' + CASE @IdField WHEN 1 THEN '[Id]' ELSE 'NULL' END + '
, ' + @columnName + '
FROM
' + @database + '.' + @schema + '.' + @tableName + ' WITH (NOLOCK)
WHERE
master.dbo.fn_regex_CS(@searchString, ' + @columnName + ') <> 0'

-- Show and execute the sql
IF @debug = 1 PRINT @sql

EXEC sp_executeSql
@sql
, N'@database NVARCHAR(255)
, @tableName NVARCHAR(255)
, @columnName NVARCHAR(255)
, @searchString NVARCHAR(255)'
, @database
, @tableName
, @columnName
, @searchString

FETCH NEXT FROM searchCursor INTO
@database
, @schema
, @tableName
, @columnName
, @dataType
, @collation
, @IdField

END

CLOSE searchCursor
DEALLOCATE searchCursor

SELECT * FROM #found FOR XML RAW


-------------
Charlie
Go to Top of Page

Mindjogger
Starting Member

9 Posts

Posted - 2008-08-20 : 08:32:28
Hello Charlie,

thank you for this. It loooks really complex for me. Without any help it will take alooong time for me to understand.

As I am not very familar with SQL I am a little bit nervus about the drop commansds ;-)

IF object_Id('tempDb..#found') IS NOT NULL DROP TABLE #found
IF object_Id('tempDb..#searchList') IS NOT NULL DROP TABLE #searchList



Thank you.

B.S.
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2008-08-20 : 08:55:05
quote:
Originally posted by Mindjogger

Hello Charlie,

thank you for this. It loooks really complex for me. Without any help it will take alooong time for me to understand.

As I am not very familar with SQL I am a little bit nervus about the drop commansds ;-)

IF object_Id('tempDb..#found') IS NOT NULL DROP TABLE #found
IF object_Id('tempDb..#searchList') IS NOT NULL DROP TABLE #searchList



Thank you.

B.S.



Hi Mindjogger

Do you have a dba or similar you can go to for advice in your organisation. Who is responsible for maintaining the database? Do you have any engineers or similar that know SQL? Find someone you know and trust who can have a look and tell you what's what.

You shouldn't run *anything* you get from t internet (including here) if you can't work out if it is safe to do so.

Saying that, this script should be safe. What it does is this

1) goes onto your master database.

2) Checks to see if the function "dbo.fn_regex_CS" already exists (which it won't as I wrote it). If it does it will DROP it (DROP FUNCTION dbo.fn_regex_CS)

3) Creates the function dbo.fn_regex_CS in your master database. This function uses a call to an external visual basic script element to do the regular expression matching -- The vb elements should exist on your server already.

4) Main body of work...
4.1) Checks to see if the temp tables that it needs exist -- if they do it drops them. This is safe as they are only temp tables.

4.2) Builds up a cursor of databases on your server that match the @searchString variable

4.3) Goes through the tables of the database that are of text types and compares them to the regular expression. It adds rows that contain what you are looking for to a temp table.

4.4) Displays the results

I don't really know what else to tell you.

Best Regards,


-------------
Charlie
Go to Top of Page

Mindjogger
Starting Member

9 Posts

Posted - 2008-08-20 : 09:40:43
Hello Charlie,

you are right: do not everyone and everythinmg from web ;-)
But I would like to trust you.

Regarding your suggestion: contact someone who is responsible for the DB.
Well, that me, from today. :-(

Yes I know I should have a training and so on, and I will do so. But unfortunately I havge to solve this before end of August because the webserver was already canceld at the current provider.

We will se what we will get afterwards ;-)

Thank you for the explanations.




Thank you.

B.S.
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2008-08-20 : 10:34:10
OK.

If you've got any questions either post them here or send me an email and I'll reply.

I work 9 to half 5 but I'll pick up emails outside that

Best of Luck,


-------------
Charlie
Go to Top of Page

Mindjogger
Starting Member

9 Posts

Posted - 2008-08-20 : 10:48:13
Hello Charlie,

thank you.

Btw. what is a "Constraint Violating Yak Guru" ?

;-)

Bernhard

Thank you.

B.S.
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2008-08-20 : 10:56:43
You get that title after posting a certain amount of posts 250 I think.

I'm not sure what the Yak signifies. Others have more interesting titles.

-------------
Charlie
Go to Top of Page
   

- Advertisement -