SQL Server에서 암호화 솔트 변형 부족 수정 sa 로그인 해시

Microsoft SQL Server 2005 이상 버전에서는 여러 SQL Server 인스턴스가 기본 제공 sa 로그인에 동일한 암호화 솔트를 사용합니다. 솔트는 모든 설치에 대해 동일하기 때문에 공격자가 먼저 해시된 암호에 액세스할 수 있는 경우 특정 종류의 무차별 암호 대입 공격이 더 실용적입니다. 해시된 암호는 SQL Server의 관리자만 사용할 수 있습니다.

증상

SQL Server 2005 이상 버전에서는 암호화 솔트가 sa 로그인과 함께 생성됩니다. CHECK_POLICY 사용하도록 설정하면 사용자가 암호 기록과 일치하도록 암호를 변경할 때 암호화 솔트가 다시 생성되지 않습니다. 기본적으로 CHECK_POLICY은 SQL Server 2005에 대해 사용하도록 설정되어 있습니다. CHECK_POLICY을 사용하지 않도록 설정하면 sa 로그인에 솔트 일관성이 더 이상 필요하지 않으며 다음 암호 변경 시 새 솔트가 다시 생성됩니다.

모든 계정에 해당하지만 빌드 프로세스 중에 sa 로그인 계정이 생성됩니다. 따라서 해당 솔트는 동일한 빌드 프로세스 중에 만들어지고 SQL Server 설치 instance 중에 유지 관리됩니다.

참고 SQL Server 2008의 경우 이 문제는 정책 기반 관리 기능에서 사용하는 기본 로그인에도 영향을 주지만 위험은 줄어듭니다. 기본적으로 이러한 로그인은 사용하지 않도록 설정됩니다.

완화 기능

암호화 솔트가 여러 설치에서 동일하게 유지되더라도 암호 해시를 손상시키는 것에는 충분하지 않습니다. 이 동작을 악용하려면 악의적인 사용자가 암호 해시를 얻기 위해 SQL Server instance에 대한 관리 액세스 권한이 있어야 합니다. 모범 사례를 따르면 일반 사용자는 암호 해시를 검색할 수 없습니다. 따라서 암호화 솔트 변형의 부족을 이용할 수 없습니다.

원인

SQL Server 2005 서비스 팩 정보

이 문제를 resolve 하려면 SQL Server 2005용 최신 서비스 팩을 다운로드하십시오. 자세한 내용은 다음 문서 번호를 클릭하여 Microsoft 기술 자료 문서를 참조하세요.

913089 SQL Server 2005용 최신 서비스 팩을 구하는 방법

SQL Server 2008용 서비스 팩 정보

이 문제를 resolve 하려면 SQL Server 2008용 최신 서비스 팩을 다운로드하십시오. 자세한 내용은 다음 문서 번호를 클릭하여 Microsoft 기술 자료 문서를 참조하세요.

968382 SQL Server 2008용 최신 서비스 팩을 구하는 방법

해결 방법

SQL Server 2005 서비스 팩 2 이상 버전의 경우 다음 스크립트를 실행하여 sa 로그인 계정의 암호화 솔트를 다시 설정할 수 있습니다. 스크립트를 실행하려면 CONTROL SERVER 권한이 있는 계정으로 로그온해야 하거나 계정이 sysadmin 서버 역할의 구성원이어야 합니다. 암호화 솔트를 다시 설정한 후 sa 로그인의 암호 기록도 다시 설정된다는 점에 유의해야 합니다.

-- 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에서 이는 "적용 대상" 섹션에 나열된 Microsoft 제품에서의 문제임을 확인했습니다.
이 문제는 SQL Server 2005용 SQL Server 2005 서비스 팩 4에서 처음 수정되었습니다.
이 문제는 SQL Server 2008용 SQL Server 2008 서비스 팩 2에서 처음 수정되었습니다.

상태

Microsoft는 고객 보호를 위해 우리와 협력해 주신 다음 내용에 감사드립니다 .

추가 정보