Skip to content

Password Cracker

A brute-force and dictionary SQL login password cracker that reports blank, username-as-password and cracked accounts.

Published Jun 20, 2009

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;
An unhandled error has occurred. Reload 🗙