Исправление отсутствие шифрования солей вариации на хэш имени входа sa в SQL Server


Симптомы


В Microsoft SQL Server 2005 и более поздних версиях несколько экземпляров SQL Server использовать же криптографических соли для встроенных входа sa. Так как соль является одинаковым для всех установок, некоторые виды грубой принудительно атаки становятся более удобным, если злоумышленник сначала можно получить доступ к хешированный пароль. Хэшированные пароли, доступны только для администраторов сервера SQL Server.

Причина


В SQL Server 2005 и более поздних версиях криптографических соли создается вместе с имени входа sa. При включении CHECK_POLICY криптографических соли не обновляется при изменении пользователем пароля для согласования с истории паролей. По умолчанию значение CHECK_POLICY включен для SQL Server 2005. При отключении CHECK_POLICY соли согласованности больше не нужны для имени входа sa и новый соль генерируется при следующей смене пароля.


Хотя это справедливо для всех учетных записей, учетная запись sa создается во время процесса построения. Таким образом его соли создается во время выполнения построения и сохраняется во время экземпляр программы установки SQL Server.


Примечание. Для SQL Server 2008 эта проблема касается также имена входа по умолчанию, используемые функцией Управление на основе политики, но риск уменьшается. По умолчанию эти имена входа будут отключены.

Устранение проблем

Даже если криптографических соли остается тем же через несколько установок, не было бы достаточно для нарушения хэш пароля. Чтобы воспользоваться этой проблемы, злонамеренный пользователь придется иметь административный доступ к экземпляру SQL Server, чтобы получить хэш пароля. Если выполнены рекомендации, обычные пользователи смогут извлечь хэш пароля. Таким образом они бы не удается воспользоваться отсутствие шифрования солей вариации.

Решение


Сведения о пакете обновления для SQL Server 2005

Чтобы устранить эту проблему, получите последний пакет обновления для SQL Server 2005. Для получения дополнительных сведений щелкните следующий номер статьи базы знаний Майкрософт:
913089 как получить последний пакет обновления для SQL Server 2005

Сведения о пакете обновления для SQL Server 2008

Чтобы устранить эту проблему, получите последний пакет обновления для SQL Server 2008. Для получения дополнительных сведений щелкните следующий номер статьи базы знаний Майкрософт:
968382 Как получить последний пакет обновления для SQL Server 2008

Временное решение


Пакет обновления 2 для SQL Server 2005 или более поздних версий можно запустить следующий сценарий, чтобы сбросить криптографических соли учетной записи имени входа sa. Чтобы запустить сценарий, вам необходимо войти в систему с учетной записью, обладающей разрешениями CONTROL SERVER или учетная запись должна быть членом серверной роли sysadmin. Следует иметь в виду, что после сброса криптографических соли журнал паролей для имени входа sa, будут заменены.
-- Work around for SQL Server 2005 SP2+--
-- Sets the password policy check off for [sa]
-- Replaces [sa] password with a random byte array
-- NOTE: This effectively replaces the sa password hash with
-- a random bag of bytes, including the salt,
-- and finally sets the password policy check on again
--
-- After resetting the salt,
-- it is necessary to set the sa password,
-- or if preferred, disable sa
--
CREATE PROC #sp_set_new_password_and_set_for_sa(@new_password sysname, @print_only int = null)
AS
DECLARE @reset_salt_pswdhash nvarchar(max)
DECLARE @random_data varbinary(24)
DECLARE @hexstring nvarchar(max)
DECLARE @i int
DECLARE @sa_name sysname;

SET @sa_name = suser_sname(0x01);
SET @random_data = convert(varbinary(16), newid()) + convert(varbinary(8), newid())
SET @hexstring = N'0123456789abcdef'
SET @reset_salt_pswdhash = N'0x0100'
SET @i = 1
WHILE @i <= 24
BEGIN
declare @tempint int
declare @firstint int
declare @secondint int

select @tempint = convert(int, substring(@random_data,@i,1))
select @firstint = floor(@tempint/16)
select @secondint = @tempint - (@firstint*16)

select @reset_salt_pswdhash = @reset_salt_pswdhash +
substring(@hexstring, @firstint+1, 1) +
substring(@hexstring, @secondint+1, 1)

set @i = @i+1
END

DECLARE @sql_cmd nvarchar(max)

SET @sql_cmd = N'ALTER LOGIN ' + quotename(@sa_name) + N' WITH CHECK_POLICY = OFF;
ALTER LOGIN ' + quotename(@sa_name) + N' WITH PASSWORD = ' + @reset_salt_pswdhash + N' HASHED;
ALTER LOGIN ' + quotename(@sa_name) + N' WITH CHECK_POLICY = ON;
ALTER LOGIN ' + quotename(@sa_name) + N' WITH PASSWORD = ' + quotename(@new_password, '''') + ';'

IF( @print_only is not null AND @print_only = 1 )
print @sql_cmd
ELSE
EXEC( @sql_cmd )
go

---------------------------------------------------------------------------------------
-- Usage example:
--
DECLARE @new_password sysname

-- Use tracing obfuscation in order to filter the new password from SQL traces
-- http://blogs.msdn.com/sqlsecurity/archive/2009/06/10/filtering-obfuscating-sensitive-text-in-sql-server.aspx
--
SELECT @new_password = CASE WHEN 1=1 THEN
-- TODO: replace password placeholder below with a strong password
--
##[MUST_CHANGE: replace this placehoder with a new password]##:
ELSE EncryptByPassphrase('','') END
EXEC #sp_set_new_password_and_set_for_sa @new_password
go

DROP PROC #sp_set_new_password_and_set_for_sa
go

Для SQL Server 2008 можно запустить следующий сценарий. Чтобы запустить сценарий, вам необходимо войти в систему с учетной записью, обладающей разрешениями CONTROL SERVER или учетная запись должна быть членом серверной роли sysadmin.
-- Work around for SQL Server 2008--

------------------------------------------------------------------------
-- Set the password policy check off for [sa]
-- Reset the password
-- Set the password policy check on for [sa] once again
--
-- NOTE: The password history will be deleted
--
CREATE PROC #sp_set_new_password_and_set_for_sa(@new_password sysname, @print_only int = null)
AS
DECLARE @sql_cmd nvarchar(max);

DECLARE @sa_name sysname;

-- Get the current name for SID 0x01.
-- By default the name should be "sa", but the actual name may have been chnaged by the system administrator
--
SELECT @sa_name = suser_sname(0x01);


-- NOTE: This password will not be subject to password policy or complexity checks
-- if desired, this step can be replaced with a "throw away" password for
-- and set the real password after the check policy setting has been set
--
SELECT @sql_cmd = 'ALTER LOGIN ' + quotename(@sa_name) + ' WITH CHECK_POLICY = OFF;
ALTER LOGIN ' + quotename(@sa_name) + ' WITH PASSWORD = ' + quotename(@new_password, '''') + ';
ALTER LOGIN ' + quotename(@sa_name) + ' WITH CHECK_POLICY = ON;'

IF( @print_only is not null AND @print_only = 1 )
print @sql_cmd
ELSE
EXEC( @sql_cmd )
go

---------------------------------------------------------------------------------------
-- Usage example:
--
DECLARE @new_password sysname

-- Use tracing obfuscation in order to filter the new password from SQL traces
-- http://blogs.msdn.com/sqlsecurity/archive/2009/06/10/filtering-obfuscating-sensitive-text-in-sql-server.aspx
--
SELECT @new_password = CASE WHEN 1=1 THEN
-- TODO: replace password placeholder below with a strong password
--
##[MUST_CHANGE: replace this placehoder with a new password]##:
ELSE EncryptByPassphrase('','') END
EXEC #sp_set_new_password_and_set_for_sa @new_password
go

DROP PROC #sp_set_new_password_and_set_for_sa
go

В SQL Server 2008 с помощью следующего сценария можно сбросить криптографических соли для управления на основе политик учетных записей. Чтобы запустить сценарий, вам необходимо войти в систему с учетной записью, обладающей разрешениями CONTROL SERVER или учетная запись должна быть членом серверной роли sysadmin.
-------------------------------------------------------------------------- Set the password policy check off for the Policy principals
-- Reset the password
-- Set the password policy check on for them once again
--
-- NOTE:
-- These principals are not intended to establish connections to SQL Server
-- So this SP will also make sure they are disabled
--
CREATE PROC #sp_reset_password_and_disable(@principal_name sysname, @print_only int = null)
AS
DECLARE @random_password nvarchar(max)

SET @random_password = convert(nvarchar(max), newid()) + convert(nvarchar(max), newid())
DECLARE @sql_cmd nvarchar(max)

SET @sql_cmd = N'ALTER LOGIN ' + quotename(@principal_name) + N' WITH CHECK_POLICY = OFF;
ALTER LOGIN ' + quotename(@principal_name) + N' WITH PASSWORD = ''' + replace(@random_password, '''', '''''') + N''';
ALTER LOGIN ' + quotename(@principal_name) + N' WITH CHECK_POLICY = ON;
ALTER LOGIN ' + quotename(@principal_name) + N' DISABLE;'

IF( @print_only is not null AND @print_only = 1 )
print @sql_cmd
ELSE
EXEC( @sql_cmd )
go


EXEC #sp_reset_password_and_disable '##MS_PolicyEventProcessingLogin##';
EXEC #sp_reset_password_and_disable '##MS_PolicyTsqlExecutionLogin##';
go

SELECT name, password_hash, is_disabled FROM sys.sql_logins
go

Статус


Корпорация Майкрософт подтверждает, что это проблема продуктов Майкрософт, перечисленных в разделе "Относится к".
Это впервые ошибка была исправлена в SQL Server 2005 Пакет обновления 4 для SQL Server 2005.
Это впервые ошибка была исправлена в SQL Server 2008 Пакет обновления 2 для SQL Server 2008.

Дополнительные сведения


Корпорация Майкрософт благодарит за проведенную совместно работу по защите пользователей: