SQL Server sa oturum açma hash'inde kriptografik salt varyasyonu eksikliğini düzeltme

Microsoft SQL Server 2005 ve sonraki sürümlerde, birden çok SQL Server örneği yerleşik SA oturum açma için aynı şifreleme tuzunu kullanır. Tuz tüm kurulumlar için aynı olduğundan, saldırgan önce karma parolaya erişebilirse, belirli kaba kuvvet saldırıları daha pratik hale gelir. Karma parolalar yalnızca SQL ServerSQL Server yöneticileri tarafından kullanılabilir.

Belirtiler

SQL Server 2005 ve sonraki sürümlerde, sa girişi ile birlikte kriptografik salt oluşturulur. CHECK_POLICY etkinleştirilirse, parola geçmişiyle tutarlı olması için kullanıcı parolayı değiştirdiğinde şifreleme tuzu yeniden oluşturulmaz. Varsayılan olarak, SQL Server 2005 için CHECK_POLICY etkinleştirilmiştir. CHECK_POLICY devre dışı bırakıldığında, sa girişi için tuz tutarlılığı artık gerekli değildir ve bir sonraki parola değişikliğinde yeni bir salt oluşturulur.

Bu tüm hesaplar için geçerli olsa da, sa oturum açma hesabı derleme işlemi sırasında oluşturulur. Bu nedenle, tuzu aynı derleme işlemi sırasında oluşturulur ve bir SQL ServerSQL Server kurulumu sırasında korunur.

Not SQL Server 2008 sürümünde, bu sorun İlke Tabanlı Yönetim özelliği tarafından kullanılan varsayılan oturum açma işlemlerini de etkiler ancak risk azalır. Varsayılan olarak bu girişler devre dışıdır.

Risk Azaltıcı Etkenler

Kriptografik tuz birden fazla kurulumda aynı kalsa bile, parola karmasını tehlikeye atmak için yeterli olmayacaktır. Bu davranıştan yararlanmak için, kötü amaçlı kullanıcının parola karmasını elde etmek üzere bir SQL Server örneğine yönetici erişimi olması gerekir. En iyi uygulamalar takip edilirse, sıradan kullanıcılar parola karmasını alamaz. Bu nedenle, kriptografik tuz varyasyonu eksikliğinden yararlanamazlar.

Neden

Service pack information for SQL ServerSQL Server 2005

Bu sorunu gidermek için SQL ServerSQL Server 2005 için en son hizmet paketini edinin. Daha fazla bilgi için Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasına tıklayın:

913089 En son SQL Server 2005 hizmet paketi nasıl edinilir

Service pack information for SQL ServerSQL Server 2008

Bu sorunu gidermek için SQL ServerSQL Server 2008 için en son hizmet paketini edinin. Daha fazla bilgi için Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasına tıklayın:

968382 En son SQL Server 2008 hizmet paketi nasıl edinilir

Çözüm

SQL Server 2005 Service Pack 2 veya sonraki sürümler için, sa oturum açma hesabının şifreleme tuzunu sıfırlamak için aşağıdaki betiği çalıştırabilirsiniz. Betiği çalıştırmak için, CONTROL SERVER izinlerine sahip bir hesapla oturum açmanız gerekir veya hesabın sysadmin sunucu rolünün bir üyesi olması gerekir. Şifreleme tuzunu sıfırladıktan sonra, sa girişi için şifre geçmişinin de sıfırlanacağını bilmelisiniz.

-- 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 için aşağıdaki betiği çalıştırabilirsiniz. Betiği çalıştırmak için, CONTROL SERVER izinlerine sahip bir hesapla oturum açmanız gerekir veya hesabın sysadmin sunucu rolünün bir üyesi olması gerekir.

-- 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'de, İlke Tabanlı Yönetim oturum açma bilgileri için şifreleme tuzu, aşağıdaki betik kullanılarak sıfırlanabilir. Betiği çalıştırmak için, CONTROL SERVER izinlerine sahip bir hesapla oturum açmanız gerekir veya hesabın sysadmin sunucu rolünün bir üyesi olması gerekir.

------------------------------------------------------------------------
-- 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

Geçici çözüm

Microsoft bunun, "Şunlar için geçerlidir" bölümünde listelenen Microsoft ürünlerinde sorun olduğunu doğrulamıştır.
Bu sorun ilk olarak SQL ServerSQL Server 2005 Service Pack 4 for SQL ServerSQL Server 2005'te düzeltilmiştir.
Bu sorun ilk olarak SQL ServerSQL Server 2008 Service Pack 2 for SQL ServerSQL Server 2008'de düzeltildi.

Durum

Microsoft, müşterilerin korunmasına yardımcı olmak üzere bizimle birlikte çalıştığınız için aşağıdaki teşekkür ederiz :

Daha Fazla Bilgi