爱编程的叶一笑的网站

信息安全工程师获得者,Sandboxie-Plus开源贡献者,目前为初中生。

如何使用身份验证函数实现Windows凭据询问及验证

TestCerd.rar

函数原型

CREDUIAPI DWORD CredUIPromptForCredentialsA(
  [in, optional] PCREDUI_INFOA pUiInfo,
  [in]           PCSTR         pszTargetName,
  [in]           PCtxtHandle   pContext,
  [in, optional] DWORD         dwAuthError,
  [in, out]      PSTR          pszUserName,
  [in]           ULONG         ulUserNameBufferSize,
  [in, out]      PSTR          pszPassword,
  [in]           ULONG         ulPasswordBufferSize,
  [in, out]      BOOL          *save,
  [in]           DWORD         dwFlags
);
BOOL LogonUserW(
  [in]           LPCWSTR lpszUsername,
  [in, optional] LPCWSTR lpszDomain,
  [in, optional] LPCWSTR lpszPassword,
  [in]           DWORD   dwLogonType,
  [in]           DWORD   dwLogonProvider,
  [out]          PHANDLE phToken
);
CREDUIAPI DWORD CredUIParseUserNameA(
  [in]  PCSTR userName,
  [out] CHAR  *user,
  [in]  ULONG userBufferSize,
  [out] CHAR  *domain,
  [in]  ULONG domainBufferSize
);

CredUIParseUserName 函数从完全限定的用户名中提取域和用户帐户名。

CredUIPromptForCredentials 函数创建并显示一个可接受用户凭据信息的可配置对话框。

思路:先用第一个函数向用户询问,随后用第二个函数验证。

头文件导入:

#include<wincred.h>
#include<ntsecapi.h>

静态库链接:

#pragma comment(lib,"Secur32.lib")
#pragma comment(lib,"Credui.lib")

定义变量:

 PCREDUI_INFOW info = new CREDUI_INFOW();
  info->cbSize = sizeof(CREDUI_INFO);
 info->hbmBanner = NULL;
 info->hwndParent = NULL;
 info->pszCaptionText = L"UAC-Review";
 info->pszMessageText = L"To test";
 BOOL saved = false;
 LPWSTR username = (WCHAR*)malloc(100), password = (WCHAR*)malloc(100), appName = const_cast<WCHAR*>(L"TestCerd.exe");
memset(username, 0, 100);
memset(password, 0, 100);//动态分配内存

调用函数:

if (CredUIPromptForCredentialsW(info/*凭据窗口UI信息*/, appName, NULL/*系统保留*/, 0, username/*执行后返回包含域名的用户名*/, 100, password/*执行后返回密码*/, 100, &saved, CREDUI_FLAGS_COMPLETE_USERNAME | CREDUI_FLAGS_EXPECT_CONFIRMATION | CREDUI_FLAGS_REQUEST_ADMINISTRATOR/*仅默认枚举管理员用户*/ | CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS /*带有这个标志后TargetName可以使用程序名*/| CREDUI_FLAGS_VALIDATE_USERNAME | CREDUI_FLAGS_DO_NOT_PERSIST/*不自动保存凭据*/| CREDUI_FLAGS_INCORRECT_PASSWORD| CREDUI_FLAGS_PASSWORD_ONLY_OK) == NO_ERROR) {
    LPWSTR user = (WCHAR*)malloc(100),domain = (WCHAR*)malloc(100);//再次动态分配
    memset(user, 0, 100);
    memset(domain, 0, 100);
    CredUIParseUserNameW(username, user, 100, domain, 100);//解析用户名 "Domain\UserName" -> "Domain","UserName"
    HANDLE tempToken = NULL;
    if(LogonUser(user, domain, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &tempToken))//用提供的凭据尝试登录
        MessageBox(NULL, L"Successful Really", L"Tips", MB_OK);
    else
        MessageBox(NULL, L"Login Failed", L"Tips", MB_OK);
    CloseHandle(tempToken);//释放局部资源
    free(user);
    free(domain);
}

释放剩余资源:

clean:
    SecureZeroMemory(password, sizeof(password));
    free(username);
    free(password);


  • 评论列表
  •  叶一笑
     发布于 2024-07-06 12:32:10  回复该评论
  • B站对应视频(含实际效果演示):https://www.bilibili.com/video/BV1WM4m127N9

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.7.3

哔哩哔哩个人空间 Copyright 爱编程的叶一笑 Rights Reserved. 湘ICP备2024068966号