2017-11-15 16 views
1

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; 
    } 

} 

答えて

3

MSDNにはそれが必要条件であることを確認します:

トークンが偽装トークンでなければなりません。

また、NULLハンドルケースのために言う:

CheckTokenMembershipは、呼び出し元のスレッドの偽装トークンを使用しています。スレッドが偽装されていない場合、この関数はスレッドのプライマリトークンを複製して偽装トークンを作成します。

あなたはこれを試みることができる:

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

注:あなたの元の入力トークンはTOKEN_DUPLICATEで開かれる必要があります。 – Anders

+0

ありがとうございました。 'CheckTokenMembership'ページの最後に次のように気付いただけですが、' 'SIDがトークンに存在していても、システムはアクセスチェックでSIDを使わないかもしれません.SIDが無効になっているかSE_GROUP_USE_FOR_DENY_ONLY属性システムはアクセスチェックを実行する際に有効なSIDのみを使用してアクセスを許可します。「 'CheckTokenMembership'が信頼できない結果を返す可能性がありますか? – c00000fd

+0

私は、無効または拒否のみのSIDがアクセスを許可せず、CheckTokenMembership isMemberがそれらに対して偽であることを意味すると思います。トークン内の各SIDを自分で確認する古いNT4スタイルの方法と比較してください。拒否のみのSIDはWin2000 +とNT4スタイルが間違った結果をもたらします。 – Anders

関連する問題