验证现有用户的密码策略


11

我最近进入一种环境,其中许多数据库登录都未enforce_password_policy启用该标志。
即将进行的审核需要验证这些登录名的密码。

我使用以下查询来获取登录列表以及这些标志是打开还是关闭。

select 
    @@SERVERNAME as servername, 
    name, 
    IS_SRVROLEMEMBER('sysadmin', name) as SYSADMIN,
    type_desc,
    create_date,
    is_policy_checked,
    is_disabled,
    password_hash,
    PWDCOMPARE(name, password_hash) as UsernameAsPassword
FROM sys.sql_logins

但是,这并不能告诉我密码是否实际上遵守密码策略,因为该标志仅在创建用户时才相关。

有已知的方法来测试现有用户的密码策略遵从性吗?
我无法访问旧密码,因此我希望使用不需要它们的方法。


1
什么会议?SQL Server天?BICC?经过快速搜索,似乎没有本机函数可以快速为您提供结果。可能可以使用第三方工具。
Stijn Wynants 2015年

SQL Server天数。我也进行了一些快速搜索,除了一些仅使用字典进行字典攻击的工具以外,PWDCOMPARE()我还没有发现太多东西,不管谢谢您的努力!
Reaces

您可以在下次登录时验证该策略,并对所有在审核之前未登录的用户强制重置。与重置所有密码相比,减少了用户的烦恼。
CodesInChaos

@CodesInChaos如何在登录事件期间验证策略?
亚伦·伯特兰

Answers:


15

这在您的用户中可能并不流行,但是我相信您唯一可以确定的方法是对每次SQL登录强制使用更改密码CHECK_POLICY = ON。这将生成一组ALTER LOGIN密码为空的命令,您可以更新查询,为它们提供一个通用密码,也可以使用单个密码手动更新每个密码-只需确保它们符合您的策略即可。当然,您需要确保密码策略与您期望的一样复杂,并且已启用(控制面板>管理工具>本地安全策略>帐户策略>密码策略>密码必须满足复杂性要求)。

SELECT N'ALTER LOGIN ' + QUOTENAME(name) 
  + N' WITH PASSWORD = N'''' MUST_CHANGE, CHECK_POLICY = ON;' 
  FROM sys.sql_logins 
  --WHERE is_policy_checked = 0;

史蒂夫·琼斯(Steve Jones)不久前就写了这个。请注意-由于我在下面发现的内容-您不能依靠它is_policy_checked = 1来表示密码实际上符合您当前的政策,因为登录名可能是使用哈希密码创建的(在这种情况下,纯文本密码不能选中)或禁用了本地复杂度策略(仍会导致is_policy_checked = 1)。

我认为可行的另一种方法是尝试为每个登录名创建一个副本,其当前值为password_hashCHECK_POLICY = ON,并记录每个失败的登录名。但是,这是行不通的 -即使使用CHECK_POLICY = ON,它也不会对已散列的密码进行任何验证。我将包括后代代码-但是,从设计上讲,根本无法检查该政策。

SELECT N'BEGIN TRY
  CREATE LOGIN ' + QUOTENAME(N'copy_of_' + name) 
    + N' WITH PASSWORD = ' 
    + CONVERT(NVARCHAR(255), password_hash, 1)
    + ' HASHED, CHECK_POLICY = ON;
  DROP LOGIN ' + QUOTENAME(N'copy_of_' + name) + ';
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 15118
    PRINT N''' + REPLACE(name, '''', '''''') 
      + N' was not complex enough.'';
END CATCH'
FROM sys.sql_logins;

我个人认为这是一个错误。如果该语法允许我使用哈希密码创建登录名,并且可以规定该密码必须符合我的复杂性策略,则它应该会产生错误或警告,表明实际上未检查该策略。

更新:我针对此行为提出了一个错误。


另一个麻烦是,我确实可以肯定以前的管理员在输入易于记忆的密码后刚刚检查了此策略。select @@SERVERNAME as servername, name FROM sys.sql_logins where PWDCOMPARE(name, password_hash) = 1 AND is_policy_checked = 1;给出了几个积极的结果。因此,我必须对所有登录名执行此操作,而不仅仅是is_policy_checked关闭登录名。
Reace

@Reaces可能。否则Windows中的密码策略可能很弱或已禁用,因此尝试强制执行该策略无济于事。
亚伦·伯特兰

我只是尝试在第二台服务器上创建同一用户,但密码验证失败。所以我猜想复杂度检查是可行的。我喜欢重新创建用户副本的想法!我将着手创建一个能够做到这一点的脚本!编辑:实际上我可以只使用sp_help_revlogin做繁重的工作。
收起

“它不会对已经散列的密码执行任何验证”它将如何执行?如果您只知道哈希而不是普通密码,则无法检查密码的复杂性。您可能会猜到密码,但是对于像样的密码哈希来说,这将是非常昂贵的,因为密码哈希的整个方面都阻碍了纯文本密码的恢复。
CodesInChaos

@CodesInChaos我知道,这就是我的意思……我说“不会”,但也可能写了“不可能”……
亚伦·贝特朗

4

您不可能获得100%的准确度。尽管您可以PWDCOMPARE用来检查弱密码列表(您可以将其添加到弱密码列表中并进行比较)。

我已经编写了一个类似的脚本来进行比较并为您提供结果。我已将其发布在github上

编辑:

现在,您可以在csv中拥有一个弱密码列表,然后将dbatools Test-DbaLoginPassword-Dictionaryswitch 配合使用 (指定要包含在弱密码测试中的密码列表。)


如果我必须自己审核特定用户的密码,我非常想使用您的脚本。但是,不知道审计师将要做什么,而只是确保所有内容都符合策略并依赖于创建策略的人员。不过谢谢!+1
Reace

0

每个SQL登录名的密码策略仅是打开或关闭的标志。如果选中了密码策略标志,则将强制执行操作系统中的Windows密码策略。

有关设置CHECK_POLICY和CHECK_EXPIRATION时会发生的情况的详细信息,请查看CREATE LOGIN文档。

您可以通过检查sys.sql_logins中的is_policy_checked和is_expiration_checked列来查看每个SQL用户的设置。

如下所示:

SELECT name,
create_date,
modify_date,
LOGINPROPERTY(name, 'DaysUntilExpiration') DaysUntilExpiration,
LOGINPROPERTY(name, 'PasswordLastSetTime') PasswordLastSetTime,
LOGINPROPERTY(name, 'IsExpired') IsExpired,
LOGINPROPERTY(name, 'IsMustChange') IsMustChange
From sys.sql_logins ;

对于SQL Server身份验证登录名:

select * from sys.server_principals where type in ('U','G') -将显示可以通过Windows身份验证访问SQL Server的登录名和组。


因为我已经在使用类似的查询,所以我的问题有所更新。我的主要问题是,我需要向老板保证密码符合策略,但是不知道密码,我不知道该怎么做。
收起
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.