You are currently offline, waiting for your internet to reconnect

Correcting the lack of cryptographic salt variation on SQL Server sa login hash

Extended support for SQL Server 2005 ends on April 12, 2016

If you are still running SQL Server 2005 after April 12, 2016, you will no longer receive security updates and technical support. We recommend upgrading to SQL Server 2014 and Azure SQL Database to achieve breakthrough performance, maintain security and compliance, and optimize your data platform infrastructure. Learn more about the options for upgrading from SQL Server 2005 to a supported version here.

SYMPTOMS
In Microsoft SQL Server 2005 and in later versions, multiple instances of SQL Server use the same cryptographic salt for the built-in sa login. Because the salt is the same for all installations, certain kinds of brute force attacks become more practical if the attacker can first gain access to the hashed password. Hashed passwords are available only to the administrators of SQL Server.
CAUSE
In SQL Server 2005 and in later versions, the cryptographic salt is generated together with the sa login. If CHECK_POLICY is enabled, the cryptographic salt is not regenerated when the user changes the password in order to be consistent with the password history. By default, CHECK_POLICY is enabled for SQL Server 2005. When the CHECK_POLICY is disabled, the salt consistency is no longer needed for the sa login, and a new salt is regenerated on the next password change.

Although this is true for all accounts, the sa login account is generated during the build process. Therefore, its salt is created during the same build process and is maintained during an instance of SQL Server setup.

Note For SQL Server 2008, this issue also affects the default logins that are used by Policy Based Management feature but the risk is reduced. By default, these logins are disabled.

Mitigations

Even if the cryptographic salt remains the same across multiple installations, it would not be sufficient to compromise the password hash. To exploit this behavior, the malicious user would have to have administrative access to an instance of SQL Server in order to obtain the password hash. If best practices are followed, ordinary users will be unable to retrieve the password hash. Therefore, they would be unable to exploit the lack of cryptographic salt variation.
RESOLUTION

Service pack information for SQL Server 2005

To resolve this problem, obtain the latest service pack for SQL Server 2005. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
913089 How to obtain the latest service pack for SQL Server 2005

Service pack information for SQL Server 2008

To resolve this problem, obtain the latest service pack for SQL Server 2008. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
968382How to obtain the latest service pack for SQL Server 2008
WORKAROUND
For SQL Server 2005 Service Pack 2 or later versions, you can run the following script to reset the cryptographic salt of the sa login account. To run the script, you must be logged on with an account that has CONTROL SERVER permissions, or the account has to be a member of the sysadmin server role. You should be aware that, after you reset the cryptographic salt, the password history for the sa login will also be reset.
-- 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('','') ENDEXEC #sp_set_new_password_and_set_for_sa @new_passwordgoDROP PROC #sp_set_new_password_and_set_for_sa go
For SQL Server 2008, you can run the following script. To run the script, you must be logged on with an account that has CONTROL SERVER permissions, or the account has to be a member of the sysadmin server role.
-- 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('','') ENDEXEC #sp_set_new_password_and_set_for_sa @new_passwordgoDROP PROC #sp_set_new_password_and_set_for_sa go
In SQL Server 2008, the cryptographic salt for the Policy Based Management logins can be reset by using the following script. To run the script, you must be logged on with an account that has CONTROL SERVER permissions, or the account has to be a member of the sysadmin server role.
-------------------------------------------------------------------------- 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 )goEXEC #sp_reset_password_and_disable '##MS_PolicyEventProcessingLogin##';EXEC #sp_reset_password_and_disable '##MS_PolicyTsqlExecutionLogin##';goSELECT name, password_hash, is_disabled FROM sys.sql_loginsgo
STATUS
Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.
This problem was first corrected in SQL Server 2005 Service Pack 4 for SQL Server 2005.
This problem was first corrected in SQL Server 2008 Service Pack 2 for SQL Server 2008.
MORE INFORMATION
Microsoft thanks the following for working with us to help protect customers:
sql2005 sql2008
Properties

Article ID: 980671 - Last Review: 11/03/2010 18:55:00 - Revision: 4.0

Microsoft SQL Server 2005 Developer Edition, Microsoft SQL Server 2005 Enterprise Edition, Microsoft SQL Server 2005 Enterprise Edition for Itanium-based Systems, Microsoft SQL Server 2005 Enterprise X64 Edition, Microsoft SQL Server 2005 Standard Edition, Microsoft SQL Server 2005 Standard X64 Edition, Microsoft SQL Server 2005 Workgroup Edition, Microsoft SQL Server 2008 Developer, Microsoft SQL Server 2008 Enterprise, Microsoft SQL Server 2008 Standard, Microsoft SQL Server 2008 Web, Microsoft SQL Server 2008 Workgroup

  • kbpasswords kbexpertiseadvanced kbsurveynew kbprb KB980671
Feedback
oFirePV = 1; var varClickTracking = 1; var varCustomerTracking = 1; var Route = "76500"; var Ctrl = ""; document.write(" ;" class="ng-binding" id="language-es-sv">El Salvador - Español
Panamá - Español
Uruguay - Español
대한민국 - 한국어
España - Español
Paraguay - Español
Venezuela - Español
id=1&t=">=4050&did=1&t="> var varCustomerTracking = 1; var Route = "76500"; var Ctrl = ""; document.write(" ')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?"> >>