Password Cracker
A brute-force and dictionary SQL login password cracker that reports blank, username-as-password and cracked accounts.
The original SQL Server login password cracker - for ethical security probing of your own systems only. It pulls every non-Windows login from syslogins, then works through four attack vectors in order: blank passwords, password equals username (via PWDCOMPARE), a one-character ASCII brute force, and finally a dictionary loaded from C:\Passwords.txt with BULK INSERT. The final report lists each login with the cracked password if found, flags whether it is an admin account, and shows which vector succeeded.
--Check if any of our temporary objects already exist
IF (OBJECT_ID('tempdb..#tLogins') IS NOT NULL)
DROP TABLE #tLogins;
IF (OBJECT_ID('tempdb..#tBruteDict') IS NOT NULL)
DROP TABLE #tBruteDict;
IF (OBJECT_ID('tempdb..#tUserDict') IS NOT NULL)
DROP TABLE #tUserDict;
IF (OBJECT_ID('tempdb..#tBruteCS') IS NOT NULL)
DROP TABLE #tBruteCS;
GO
--Variables for use throughout the script
DECLARE @Counter INT;
SET NOCOUNT ON
--Create tables to hold temporary data
CREATE TABLE #tLogins(
[UID] INT IDENTITY(1,1) NOT NULL,
[Login] nvarchar(128) NOT NULL,
[SID] VARBINARY(85) NOT NULL,
[Password] nvarchar(128) NULL,
[PasswordHash] VARBINARY(256) NULL,
[IsAdmin] BIT DEFAULT(0) NOT NULL,
[BlankPass] BIT DEFAULT(0) NOT NULL,
[SamePass] BIT DEFAULT(0) NOT NULL,
[BrutePass] BIT DEFAULT(0) NOT NULL
);
CREATE TABLE #tBruteDict(
[RawText] nvarchar(128) NOT NULL
);
CREATE TABLE #tBruteCS(
[RawText] nvarchar(128) NOT NULL
);
CREATE TABLE #tUserDict(
[RawText] nvarchar(128) NOT NULL
);
--Create a list of the regular (non-nt) users
INSERT INTO #tLogins( [SID], [Login], [IsAdmin], [PasswordHash] )
SELECT
L.[sid],
L.[name],
CASE
WHEN L.[sysadmin] = 1 OR L.[securityadmin] = 1 OR L.[serveradmin] = 1 OR L.[setupadmin] = 1 OR L.[processadmin] = 1 OR L.[diskadmin] = 1 THEN 1
ELSE 0
END,
LX.password_hash AS [password]
FROM [master]..[syslogins] AS L
LEFT JOIN sys.sql_logins LX ON L.sid = LX.sid
WHERE L.[isntname] = 0;
--Identify users with blank passwords
UPDATE #tLogins
SET [BlankPass] = 1
FROM #tLogins
WHERE [PasswordHash] IS NULL;
--Identify users with password = username
UPDATE #tLogins
SET [SamePass] = 1, [Password] = [Login]
WHERE PWDCOMPARE( [Login], [PasswordHash] ) = 1;
--Identify users with one or two character (ASCII 0-255) passwords
SET @Counter = 0;
WHILE @Counter <= 255
BEGIN
INSERT INTO #tBruteCS( [RawText] )
VALUES( CHAR(@Counter) );
SET @Counter = @Counter + 1;
END
INSERT INTO #tBruteDict( [RawText] )
SELECT Src.[RawText]
FROM #tBruteCS AS Src
--INSERT INTO #tBruteDict( [RawText] )
--SELECT Src.[RawText]+New.[RawText]
--FROM #tBruteDict AS Src, #tBruteCS AS New;
DROP TABLE #tBruteCS;
UPDATE #tLogins
SET [BrutePass] = 1, [Password] = Dict.[RawText]
FROM #tLogins AS Src
LEFT JOIN #tBruteDict AS Dict ON PWDCOMPARE( Dict.[RawText], Src.[PasswordHash] ) = 1
WHERE Dict.[RawText] IS NOT NULL AND Src.[BrutePass] = 0 AND Src.[BlankPass] = 0 AND Src.[SamePass] = 0;
DROP TABLE #tBruteDict;
--Identify users with passwords from our dictionary
BEGIN
BULK INSERT #tUserDict FROM 'C:\Passwords.txt'
WITH(
DATAFILETYPE = 'char'
);
UPDATE #tLogins
SET [BrutePass] = 1, [Password] = Dict.[RawText]
FROM #tLogins AS Src
LEFT JOIN #tUserDict AS Dict ON PWDCOMPARE( Dict.[RawText], Src.[PasswordHash] ) = 1
WHERE Dict.[RawText] IS NOT NULL AND Src.[BrutePass] = 0 AND Src.[BlankPass] = 0 AND Src.[SamePass] = 0;
END
DROP TABLE #tUserDict;
--Reset nocount
SET NOCOUNT OFF
--Report any users whose logins were weak
SELECT
[Login] AS [Username],
ISNULL( [Password], '-- currently unknown --' ) AS [Password],
CASE
WHEN [BlankPass] = 1 OR [SamePass] = 1 OR [BrutePass] = 1 THEN 1
ELSE 0
END AS [Cracked?],
[IsAdmin] AS [Admin User?],
[BlankPass] AS [Blank Password?],
[SamePass] AS [Username = Password?],
[BrutePass] AS [Password Bruteforced?]
FROM #tLogins
ORDER BY [Login];
DROP TABLE #tLogins;