如何检查用户是空密码
2022-05-27 / Hell

前情提要,工作代码有系统配置检查能力,其中一项是检测用户是否设置密码。最近收到一个客户反馈,客户环境是域环境,设置了密码尝试次数,超过即锁定账户。一启用我们的功能,用户一会就会被锁定,并且是大范围出现。
首先,我们看看目前的代码:

1
2
3
4
5
6
7
8
bool CheckEmptyPassword(const wchar_t* domainname, const wchar_t* username)
{
NET_API_STATUS status = ::NetUserChangePassword(domainname, username, L"", L"");
if (NERR_Success == status || NERR_PasswordTooShort == status) {
return true;
}
return false;
}

这代码真的是让人醍醐灌顶,检测是否设置密码居然是尝试改一下密码。😢
于是我潇洒的改成了这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bool CheckEmptyPassword(const wchar_t* domainname, const wchar_t* username)
{
bool ret = false;
LPUSER_INFO_23 user_info = nullptr;

do
{
auto status = NetUserGetInfo(domainname, username, 23, (LPBYTE*)&user_info);
if (NERR_Success != status)
{
break;
}

if ((user_info->usri23_flags & UF_PASSWD_NOTREQD) != UF_PASSWD_NOTREQD)
{
// 非空密码
break;
}

ret = true;
} while (false);

if (user_info != nullptr)
{
NetApiBufferFree(user_info);
user_info = nullptr;
}

return ret;
}

简单测试了一下就发布了……🤣
上面这段代码看起来没毛病对吧。不,有毛病,还不小。我们来看两张图:
图1
图2
通过上面两幅图各位有没有发现什么问题?
特么的这个NetUserGetInfo获取到的账户是否需要密码的状态是不会变化的!这个值是账户创建时的值,后面不会变!~!@#¥%……&*()——
那么Windows是如何检测用户是否有密码的呢?毕竟可以根据用户是否有密码而显示Create a password for your accout以及Remove your password,这个值是没问题的。
通过逆向分析后发现,Windows 7是这样判断用户密码是否为空的:
Windows 7判断密码是否为空
艹,一种植物。
所以Windows 7就是用这种方法检测账户是否有密码,那么Windows 7如何加域后,设置密码错误次数应该也会被锁定才对。于是搭建了域环境做测试,结果是会被锁定,我设置5次超时。打开6次用户设置后注销,我被锁定了😅
那么Windows 11有改进么?
Windows 11判断密码是否为空
看来还是不错,有一套API能获取状态,那么我们只需要抄一遍就好了✅

PermaLink:
https://lazywang.life/2022/05/27/how-to-check-user-has-empty-password/