如何使用 CredUIPromptForWindowsCredentials 驱动我的凭据提供程序

问题描述

我一直在研究凭据提供程序,并且一直在通过日志记录对其进行调试。最近了解到 CredUIPromptForWindowsCredentials() API 能够从登录屏幕或远程桌面连接以外的地方调用它。此时我似乎可以显示我的凭据的唯一方法是将最后一个参数设置为 CREDUIWIN_SECURE_PROMPT。我尝试了各种标志方案,但都没有运气。我的 CP 工作正常,这不是问题。问题是更容易调试。只有一次我让我的笔记本电脑无法启动时不得不进入救援模式。 ;) 使用 CREDUIWIN_SECURE_PROMPT 标志的问题是我无法访问调试器,因为登录接管了屏幕,我无法回到调试器。我想唯一的解决方法是使用此 API 在另一台机器上进行远程调试,但我不想为此烦恼。

我的 CP 注册在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{55157584-ff0f-48ce-9178-a4e290901663} 并且属性是“MyCredProvider”(对于这个例子)。 (GUID,道具名称已更改以保护有罪者。同时忽略 LsaString,其中副本上会发生不好的事情——我不会这样做。)

有没有办法在不使用安全提示的情况下获得我的自定义 CP?

#include <windows.h>
#include <iostream>
#include <EvoApi.h>
#include <decrypt.h>
#include <atlbase.h>
#include <Lmwksta.h>
#include <StrSafe.h>
#include <LMAPIbuf.h>
#include <LMJoin.h>
#include <wincred.h>
#include <NTSecAPI.h>

#pragma warning(disable : 4996)
#pragma comment(lib,"netapi32.lib")
#pragma comment(lib,"credui.lib")
#pragma comment(lib,"secur32")

using namespace std;


template <size_t SIZE = 256>
struct LsaString : public LSA_STRING
{

    LsaString()
    {
        MaximumLength = SIZE;
        Length = 0;
        Buffer = pBuf.get();
    }

    LsaString(LPCSTR pWhat)
    {
        MaximumLength = SIZE;
        Length = 0;
        Buffer = pBuf.get();
        Init(pWhat);
    }
    void Init(LPCSTR pWhat)
    {
        size_t len = strlen(pWhat);
        if (len >= SIZE)
            throw;
        strcpy(Buffer,pWhat);
        Length = (USHORT) len;
    }
    unique_ptr<char[]> pBuf = make_unique< char[] >(SIZE);
};

int _tmain(int argc,wchar_t* argv[])
{
#if 1
    wstring me(_T("MYLOGING"));
    wstring url(_T("Header"));
    wstring message(_T("Enter credentials for ..."));

    CREDUI_INFOW credInfo;
    credInfo.pszCaptionText = url.c_str();
    credInfo.hbmBanner = nullptr;
    credInfo.hwndParent = NULL;
    credInfo.pszMessageText = message.c_str();
    credInfo.cbSize = sizeof(CREDUI_INFOW);

    ULONG authPackage = 0;

    LSAHANDLE lsaHandle;
    LsaConnectUntrusted(&lsaHandle);

    LsaString<> lsaString("MyCredProvider");
    //LsaString<> lsaString(MICROSOFT_KERBEROS_NAME_A); // works ... as far as finding in LsaLookupAuth...
    //LsaString<> lsaString(NEGOssp_NAME_A); // works ... as far as finding in LsaLookupAuth...


    ULONG ulPackage = 0;
    LsaLookupAuthenticationPackage(lsaHandle,&lsaString,&ulPackage);

    void* pBlob;
    ULONG blobSize = 0;

    DWORD dwFlags = CREDUIWIN_GENERIC; //CREDUIWIN_SECURE_PROMPT

    CredUIPromptForWindowsCredentials(&credInfo,&ulPackage,NULL,&pBlob,&blobSize,FALSE,dwFlags);
    if (pBlob) CoTaskMemFree(pBlob);

    return 0;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)