【问题标题】:CreateProcessAsUser and createevent permissionsCreateProcessAsUser 和 createevent 权限
【发布时间】:2020-01-11 16:31:57
【问题描述】:

我正在创建一个侦听端口的应用程序,当客户端发出请求时,它会使用 LogonUser,CreateProcessAsUser 与不同的用户生成一个新进程。

我已经使用 CreateEvent() 函数设置了 2 个事件,以向子进程发出 WSADuplicateSocket 已准备好通过内存映射文件将 SOCKADD_STORAGEW 结构传递给子进程的信号。

子进程中的 OpenEvent() 在从应用程序生成时不断失败,并出现错误 5(拒绝访问)。

如果我使用(shift + 右键单击​​,运行方式)手动运行子/客户端,则 OpenEvent 函数成功地设法打开事件。

该事件是在全局命名空间 (Global\myevent) 中创建的,出于测试目的,我创建了一个 null Dacl(我已使用 winobj 验证了该事件的权限)传递给 CreateEvent() 函数。

我看不出我缺少什么。

这里是相关代码sn-p:

服务器:

SECURITY_ATTRIBUTES sa;
CreateNullDacl(&sa);


if ((ghParentFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szParentEventName)) == NULL) {
    fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
    return false;
}

if ((ghChildFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szChildEventName)) == NULL) {
    fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
    CloseHandle(ghParentFileMappingEvent);
    return false;
}





PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
SECURITY_ATTRIBUTES procSa;
CreateNullDacl(&procSa);

HANDLE htok;
if (!LogonUser(chall->user, ".", chall->pass, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
    fprintf(stderr, "LogonUser() failed: %d\n", GetLastError());
    return false;

}


if(CreateProcessAsUser(htok, 0, szChildComandLineBuf, &procSa, 0, FALSE, NULL, NULL, "C:\\Users\\ch99", &si, &pi)) {
 //... 
}

从 CreateProcessAsUser() 生成的客户端

 if ((ghParentFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szParentEventName)) == 0)  // return 5 , access denied
{
    fprintf(fp, "OpenParentEvent failed: %d\n", GetLastError());
    return INVALID_SOCKET;
}

if ((ghChildFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szChildEventName)) == 0) { // return 5 access denied
    fprintf(fp, "OpenChildEvent failed: %d\n", GetLastError());
    CloseHandle(ghParentFileMappingEvent);
    ghParentFileMappingEvent = NULL;
    return INVALID_SOCKET;
}

感谢您的回复。

【问题讨论】:

标签: c++ winapi winsock2


【解决方案1】:

在尝试了这么多不同的事情之后,CreateEvent() 不断返回访问被拒绝。

我发现了一个丑陋的解决方法:在传递给 CreateEvent() 的 SECURITY_ATTRIBUTES 中,我将 bInheritHandle 设置为 TRUE,并将句柄值传递给参数中的子进程。

此时我可以在句柄上使用 WaitForSingleObject() 。

我真的很想知道为什么它不像我的第一个问题中描述的那样工作......

【讨论】:

    【解决方案2】:

    基于CreateProcessAsUser的文档:

    代表用户的主要令牌的句柄。手柄必须 拥有 TOKEN_QUERYTOKEN_DUPLICATETOKEN_ASSIGN_PRIMARY 访问权限 权利。

    以下代码适用于我:

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &htok))
        printf("OpenProcessToken() failed: %d\n", GetLastError());
    if (!CreateProcessAsUser(htok, L"childProc.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        printf("CreateProcessAsUser() failed: %d\n", GetLastError());
    }
    

    或者您可以使用CreateProcessWithToken 代替(这需要以管理员身份运行):

    HANDLE htok;
    if (!LogonUser(L"userName", L"domain", L"password", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
        printf("LogonUser() failed: %d\n", GetLastError());
        return false;
    }
    
    if (!CreateProcessWithTokenW(htok, LOGON_WITH_PROFILE,L"childProc.exe", NULL, 0, NULL, NULL, &si, &pi)) {
        printf("CreateProcessAsUser() failed: %d\n", GetLastError());
    }
    

    以上两种方法,子进程都可以成功打开事件

    对于您的代码,我在调用 CreateProcessAsUser 时收到错误代码 1314(客户端未持有所需的权限。)。指出我遗漏了什么并为您的问题重现步骤。

    【讨论】:

    • 您好,感谢您的宝贵时间。如果我使用, CreateProcessWithTokenW() (作为管理员或不是)它返回 5 ,访问被拒绝。如果我用我的参与用户“经纪人”运行它,它返回 1314。我也面临 1314 与 CreateProcessAsUser,顺便说一句,授予后,SeAssignPrimaryTokenPrivilege,SeCreateTokenPrivilege 和 SeIncreaseQuotaPrivilege; CreateProcessAsUser() 成功。我将尝试在本地服务帐户下运行服务器。
    猜你喜欢
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    相关资源
    最近更新 更多