Correction de l’absence de variation de sel de chiffrement sur SQL Server sa login hash

Dans Microsoft SQL Server 2005 et dans les versions ultérieures, plusieurs instances de SQL Server utilisent le même sel de chiffrement pour la connexion SA intégrée. Comme le sel est le même pour toutes les installations, certains types d’attaques par force brute deviennent plus pratiques si l’attaquant peut d’abord accéder au mot de passe haché. Les mots de passe hachés ne sont disponibles que pour les administrateurs de SQL Server.

Symptômes

Dans SQL Server 2005 et les versions ultérieures, le sel de chiffrement est généré avec le nom d’accès SA. Si CHECK_POLICY est activé, le sel cryptographique n’est pas régénéré lorsque l’utilisateur modifie le mot de passe afin d’être cohérent avec l’historique des mots de passe. Par défaut, CHECK_POLICY est activé pour SQL Server 2005. Lorsque le CHECK_POLICY est désactivé, la cohérence du sel n’est plus nécessaire pour la connexion sa et un nouveau sel est régénéré lors de la prochaine modification de mot de passe.

Bien que cela soit vrai pour tous les comptes, le compte de connexion sa est généré pendant le processus de construction. Par conséquent, son sel est créé au cours du même processus de génération et est conservé pendant une instance de configuration SQL Server.

Remarque Pour SQL Server 2008, ce problème affecte également les noms d’accès par défaut qui sont utilisés par la fonctionnalité de gestion basée sur des stratégies, mais le risque est réduit. Par défaut, ces noms d’accès sont désactivés.

Atténuations

Même si le sel cryptographique reste le même sur plusieurs installations, il ne serait pas suffisant pour compromettre le hachage du mot de passe. Pour exploiter ce comportement, l’utilisateur malveillant devrait avoir un accès administratif à une instance de SQL Server afin d’obtenir le hachage de mot de passe. Si les meilleures pratiques sont suivies, les utilisateurs ordinaires seront incapables de récupérer le hachage de mot de passe. Par conséquent, ils seraient incapables d’exploiter l’absence de variation du sel cryptographique.

Cause

Informations sur les Service Packs pour SQL Server 2005

Pour résoudre ce problème, procurez-vous le dernier Service Pack pour SQL Server 2005. Pour plus d’informations, cliquez sur le numéro ci-dessous pour afficher l’article correspondant dans la Base de connaissances Microsoft :

913089 Comment obtenir le dernier Service Pack pour SQL Server 2005

Informations sur les Service Packs pour SQL Server 2008

Pour résoudre ce problème, procurez-vous le dernier Service Pack pour SQL Server 2008. Pour plus d’informations, cliquez sur le numéro ci-dessous pour afficher l’article correspondant dans la Base de connaissances Microsoft :

968382 Comment obtenir le dernier Service Pack pour SQL Server 2008

Résolution

Pour SQL Server 2005 Service Pack 2 ou versions ultérieures, vous pouvez exécuter le script suivant pour réinitialiser le sel de chiffrement du compte de connexion SA. Pour exécuter le script, vous devez être connecté avec un compte disposant des autorisations CONTROL SERVER ou le compte doit être membre du rôle serveur sysadmin. Vous devez savoir qu’après avoir réinitialisé le sel cryptographique, l’historique des mots de passe pour sa login sera également réinitialisé.

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

Pour SQL Server 2008, vous pouvez exécuter le script suivant. Pour exécuter le script, vous devez être connecté avec un compte disposant des autorisations CONTROL SERVER ou le compte doit être membre du rôle serveur 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

Dans SQL Server 2008, le sel de chiffrement pour les connexions de gestion basée sur des stratégies peut être réinitialisé à l’aide du script suivant. Pour exécuter le script, vous devez être connecté avec un compte disposant des autorisations CONTROL SERVER ou le compte doit être membre du rôle serveur 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

Solution de contournement

Microsoft a confirmé qu’il s’agissait d’un problème dans les produits Microsoft répertoriés dans la section « S’applique à ».
Ce problème a été corrigé pour la première fois dans SQL Server 2005 Service Pack 4 pour SQL Server 2005.
Ce problème a été corrigé pour la première fois dans SQL Server 2008 Service Pack 2 pour SQL Server 2008.

État

Microsoft remercie les personnes suivantes de collaborer avec nous pour aider à protéger les clients :

Informations supplémentaires