【问题标题】:Win32 API : User Impersonation technique to run a process as some other user?Win32 API:用户模拟技术以其他用户身份运行进程?
【发布时间】:2013-02-15 06:20:19
【问题描述】:

我正在编写一个应用程序,它以特权较低的用户身份运行第三方可执行文件 在 Windows 上。为此,我使用了以下 Win32 API 函数:

LogonUser(L"UserName", L"Domain", NULL, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, &hToken)

然后调用

CreateProcessAsUser() 

使用 hToken 我必须运行该进程。我启动这个可执行文件的实际程序是以管理员身份运行的。我的疑问是:

  1. 如果启用了 UAC(用户帐户控制)。这行得通吗?

  2. 我需要多次创建进程。我可以使用hToken by 保存在某处。

  3. 确实 CreateProcessAsUser() 适用于不同的组合 域\用户,即 .\Administrator 或 \Administrator 或 域\用户名等..??

【问题讨论】:

  • 自己试试吧。 LogonUser 确实返回了交互式会话的受限令牌,但尚不清楚其中有多少是受限的。至于 #2,您可以在生成进程时复制令牌。

标签: c++ winapi process


【解决方案1】:

MSDN says:“一般来说,最好使用CreateProcessWithLogonW 来创建具有备用凭据的进程。”下面example 演示了如何调用这个函数。

#include <windows.h>
#include <stdio.h>
#include <userenv.h>

void DisplayError(LPWSTR pszAPI)
{
    LPVOID lpvMessageBuffer;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, GetLastError(), 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
        (LPWSTR)&lpvMessageBuffer, 0, NULL);

    //
    //... now display this string
    //
    wprintf(L"ERROR: API        = %s.\n", pszAPI);
    wprintf(L"       error code = %d.\n", GetLastError());
    wprintf(L"       message    = %s.\n", (LPWSTR)lpvMessageBuffer);

    //
    // Free the buffer allocated by the system
    //
    LocalFree(lpvMessageBuffer);

    ExitProcess(GetLastError());
}

void wmain(int argc, WCHAR *argv[])
{
    DWORD     dwSize;
    HANDLE    hToken;
    LPVOID    lpvEnv;
    PROCESS_INFORMATION pi = {0};
    STARTUPINFO         si = {0};
    WCHAR               szUserProfile[256] = L"";

    si.cb = sizeof(STARTUPINFO);

    if (argc != 4)
    {
        wprintf(L"Usage: %s [user@domain] [password] [cmd]", argv[0]);
        wprintf(L"\n\n");
        return;
    }

    //
    // TO DO: change NULL to '.' to use local account database
    //
    if (!LogonUser(argv[1], NULL, argv[2], LOGON32_LOGON_INTERACTIVE, 
            LOGON32_PROVIDER_DEFAULT, &hToken))
        DisplayError(L"LogonUser");

    if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
        DisplayError(L"CreateEnvironmentBlock");

    dwSize = sizeof(szUserProfile)/sizeof(WCHAR);

    if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize))
        DisplayError(L"GetUserProfileDirectory");

    //
    // TO DO: change NULL to '.' to use local account database
    //
    if (!CreateProcessWithLogonW(argv[1], NULL, argv[2], 
            LOGON_WITH_PROFILE, NULL, argv[3], 
            CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile, 
            &si, &pi))
        DisplayError(L"CreateProcessWithLogonW");

    if (!DestroyEnvironmentBlock(lpvEnv))
        DisplayError(L"DestroyEnvironmentBlock");

    CloseHandle(hToken);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2010-11-13
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    相关资源
    最近更新 更多