代码之家  ›  专栏  ›  技术社区  ›  c00000fd

如何检查非“自”进程的组成员身份?

  •  1
  • c00000fd  · 技术社区  · 8 年前

    我正在尝试使用 this code 检查我有句柄的任意进程的安全组成员身份。但在我下面的代码中 CheckTokenMembership 失败,错误代码1309,或 ERROR_NO_IMPERSONATION_TOKEN . 我不知道我怎么能得到那个冒充令牌。。。

    void check_membership(HANDLE hProc)
    {
        HANDLE hToken;
        if(OpenProcessToken(hProc, TOKEN_QUERY, &hToken))
        {
            check_group_membership(hToken, L"Local Group", DOMAIN_ALIAS_RID_USERS);
            check_group_membership(hToken, L"Admin Group", DOMAIN_ALIAS_RID_ADMINS);
            check_group_membership(hToken, L"Domain Admin Group", DOMAIN_GROUP_RID_ADMINS);
            check_group_membership(hToken, L"Schema Admin Group", DOMAIN_GROUP_RID_SCHEMA_ADMINS);
            check_group_membership(hToken, L"Enterprise Admin Group", DOMAIN_GROUP_RID_ENTERPRISE_ADMINS);
    
            CloseHandle(hToken);
        }
    }
    
    
    void check_group_membership(HANDLE hToken, LPCTSTR pStrName, DWORD nSubauthority)
    {
        BOOL bIsMember;
        SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    
        wprintf(L"Local %s: ", pStrName);
    
        PSID pSID = NULL; 
        if(AllocateAndInitializeSid(&NtAuthority, 2,
            SECURITY_BUILTIN_DOMAIN_RID,
            nSubauthority,
            0, 0, 0, 0, 0, 0, &pSID))
        {
            bIsMember = FALSE;
            if(CheckTokenMembership(hToken, pSID, &bIsMember))
            {
                wprintf(L"%s", bIsMember ? L"Yes" : L"No");
            }
            else
            {
                wprintf(L"<CheckErr: (%d)>", GetLastError());
            }
        }
        else
        {
            wprintf(L"<SidErr: (%d)>", GetLastError());
        }
    
        wprintf(L"\n");
    
        if(pSID)
        {
            FreeSid(pSID) == NULL);
            pSID = NULL;
        }
    
    }
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   Anders    8 年前

    MSDN确认这是一项要求:

    令牌必须是模拟令牌。

    它还表示对于空句柄情况:

    CheckTokenMembership 使用调用线程的模拟令牌。如果线程没有模拟,则函数复制线程的主令牌以创建模拟令牌。

    你可以试试这个:

    HANDLE hImpToken;
    if (DuplicateTokenEx(hToken, TOKEN_QUERY, NULL, SecurityImpersonation, TokenImpersonation, &hImpToken))
    {
        CheckTokenMembership(hImpToken, ...);
        CloseHandle(hImpToken);
    }