В Microsoft SQL Server 2005 и более поздних версиях несколько экземпляров SQL Server используют одну и ту же криптографическую соль для встроенного входа в SA. Так как соль одинакова для всех установок, определенные виды атак методом подбора становятся более практичными, если злоумышленнику удается сначала получить доступ к хэшированному паролю. Хэшированные пароли доступны только администраторам SQL Server.
Проблема
В SQL Server 2005 и более поздних версиях криптографическая соль генерируется вместе с именем входа в систему. Если 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 г.
Решение
Для SQL Server 2005 с пакетом обновления 2 (SP2) или более поздних версий вы можете запустить следующий сценарий, чтобы сбросить криптографическую соль учетной записи входа SA. Чтобы запустить сценарий, необходимо войти в систему с учетной записью с разрешениями CONTROL SERVER или учетная запись должна быть членом роли сервера sysadmin. Вы должны знать, что после сброса криптографической соли история паролей для входа в систему также будет сброшена.
-- 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
Временное решение
Корпорация Майкрософт подтвердила, что это проблема продуктов Microsoft, перечисленных в разделе «Относится к».
Эта проблема была впервые исправлена в SQL Server 2005 с пакетом обновления 4 для SQL Server 2005.
Эта проблема была впервые исправлена в SQL Server 2008 с пакетом обновления 2 для SQL Server 2008.
Состояние
Корпорация Майкрософт благодарит следующих пользователей за сотрудничество с нами для защиты клиентов: