In Microsoft SQL Server 2005 und neueren Versionen verwenden mehrere Instanzen von SQL Server dasselbe kryptografische Salt für die integrierte sa-Anmeldung. Da das Salt für alle Installationen identisch ist, werden bestimmte Arten von Brute-Force-Angriffen praktischer, wenn der Angreifer zuerst Zugriff auf das gehashte Kennwort erhalten kann. Hashkennwörter sind nur für die Administratoren von SQL Server verfügbar.
Symptome
In SQL Server 2005 und neueren Versionen wird das kryptografische Salt zusammen mit der sa-Anmeldung generiert. Wenn CHECK_POLICY aktiviert ist, wird das kryptografische Salt nicht neu generiert, wenn der Benutzer das Kennwort ändert, um mit dem Kennwortverlauf konsistent zu sein. Standardmäßig ist CHECK_POLICY für SQL Server 2005 aktiviert. Wenn die CHECK_POLICY deaktiviert ist, wird die Salt-Konsistenz für die sa-Anmeldung nicht mehr benötigt, und bei der nächsten Kennwortänderung wird ein neues Salt neu generiert.
Obwohl dies für alle Konten gilt, wird das sa-Anmeldekonto während des Buildprozesses generiert. Daher wird sein Salt während desselben Buildprozesses erstellt und während einer Instance des SQL Server-Setups beibehalten.
Hinweis Für SQL Server 2008 wirkt sich dieses Problem auch auf die Standardanmeldungen aus, die von der richtlinienbasierten Verwaltungsfunktion verwendet werden, aber das Risiko wird reduziert. Standardmäßig sind diese Benutzernamen deaktiviert.
Risikominderungen
Selbst wenn das kryptografische Salt über mehrere Installationen hinweg gleich bleibt, würde es nicht ausreichen, um den Passwort-Hash zu kompromittieren. Um dieses Verhalten auszunutzen, müsste der böswillige Benutzer Administratorzugriff auf eine Instance von SQL Server haben, um den Kennworthash abzurufen. Wenn die bewährten Methoden befolgt werden, können normale Benutzer den Kennworthash nicht abrufen. Daher wären sie nicht in der Lage, den Mangel an kryptografischer Salzvariation auszunutzen.
Ursache
Service Pack-Informationen für SQL Server 2005
Um dieses Problem zu beheben, besorgen Sie sich das neueste Service Pack für SQL Server 2005. Weitere Informationen finden Sie im folgenden Artikel der Microsoft Knowledge Base:
913089 So erhalten Sie das neueste Service Pack für SQL Server 2005
Service Pack-Informationen für SQL Server 2008
Installieren Sie das neueste Service Pack für SQL Server 2008, um dieses Problem zu beheben. Weitere Informationen finden Sie im folgenden Artikel der Microsoft Knowledge Base:
968382 So erhalten Sie das neueste Service Pack für SQL Server 2008
Lösung
Für SQL Server 2005 Service Pack 2 oder höhere Versionen können Sie das folgende Skript ausführen, um den Kryptografie-Salt des SA-Anmeldekontos zurückzusetzen. Um das Skript auszuführen, müssen Sie mit einem Konto angemeldet sein, das über CONTROL SERVER-Berechtigungen verfügt, oder das Konto muss Mitglied der Serverrolle "sysadmin" sein. Sie sollten beachten, dass nach dem Zurücksetzen des kryptografischen Salts auch der Passwortverlauf für die sa-Anmeldung zurückgesetzt wird.
-- 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
Für SQL Server 2008 können Sie das folgende Skript ausführen. Um das Skript auszuführen, müssen Sie mit einem Konto angemeldet sein, das über CONTROL SERVER-Berechtigungen verfügt, oder das Konto muss Mitglied der Serverrolle "sysadmin" sein.
-- 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
In SQL Server 2008 kann das kryptografische Salt für die anmeldungen für die richtlinienbasierte Verwaltung mithilfe des folgenden Skripts zurückgesetzt werden. Um das Skript auszuführen, müssen Sie mit einem Konto angemeldet sein, das über CONTROL SERVER-Berechtigungen verfügt, oder das Konto muss Mitglied der Serverrolle "sysadmin" sein.
------------------------------------------------------------------------
-- 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
Problemumgehung
Microsoft hat bestätigt, dass dies ein Problem bei den Microsoft-Produkten ist, die im Abschnitt „Gilt für“ aufgeführt sind.
Dieses Problem wurde zuerst in SQL Server 2005 Service Pack 4 für SQL Server 2005 behoben.
Dieses Problem wurde erstmals in SQL Server 2008 Service Pack 2 für SQL Server 2008 behoben.
Status
Microsoft bedankt sich bei den folgenden Personen für die Zusammenarbeit zum Schutz unserer Kunden: