Les jetons haute intégrité * ont-ils * le groupe Administrateurs activé?

Lorsque UAC est activé et que vous vous connectez avec un compte administratif, vous obtenez deux jetons:

  • le jeton élevé; le groupe Administrateurs est activé, présente une intégrité élevée (par exemple, le label d’intégrité obligatoire SID est S-1-16-12288) et possède un type d’élévation TokenElevationTypeFull.

  • le jeton limité; le groupe Administrateurs est désactivé, présente une intégrité moyenne (S-1-16-8192) et un type d’élévation TokenElevationTypeLimited.

Ces trois facteurs correspondent-ils toujours de cette manière? En d’autres termes, le kernel exige-t-il que seuls les jetons avec le groupe Administrateurs activé puissent avoir une intégrité élevée et / ou un TokenElevationTypeFull?

Existe-t-il des circonstances dans lesquelles un processus n’aura pas le privilège Administrateurs mais fonctionnera avec une intégrité élevée et / ou TokenElevationTypeFull?

(Raison d’être de la question: la réponse affecte les manières dont un programmeur peut tester en toute sécurité des privilèges élevés. Par exemple, il est apparu ici .)

Non, le kernel n’exige pas que le niveau d’intégrité et le type d’élévation d’un jeton correspondent au statut du groupe Administrateurs. Cela signifie qu’un processus ayant un niveau d’intégrité élevé, ou TokenElevationTypeFull, n’a pas nécessairement un access administrateur.

En particulier, notez que l’utilisation de runas /trustlevel:0x20000 partir d’une invite de commande administrative se traduira par un processus qui ne dispose pas des privilèges d’administrateur, mais qui s’exécute néanmoins avec une intégrité élevée (si UAC est activé). ( Comme découvert ici. ) Je crois que cela représente un bug dans les runas .

Cet exemple de code illustre le comportement; S’il est exécuté avec le privilège administrateur, il lance un sous-processus avec le groupe d’administrateurs (et tous les privilèges, à l’exception de SeChangeNotifyPrivilege) désactivé, mais toujours en cours d’exécution avec une intégrité élevée et TokenElevationTypeFull.

 #include  #include  #include  PSID admins_sid; void get_membership(HANDLE token) { BOOL is_enabled; HANDLE itoken; if (!DuplicateToken(token, SecurityIdentification, &itoken)) { printf("DuplicateToken: %u\n", GetLastError()); return; } if (!CheckTokenMembership(itoken, admins_sid, &is_enabled)) { printf("CheckTokenMembership: %u\n", GetLastError()); CloseHandle(itoken); return; } CloseHandle(itoken); printf("Administrators group enabled: %u\n", is_enabled); return; } void get_integrity(HANDLE token) { char buffer[4096]; char * ssortingngsid; TOKEN_MANDATORY_LABEL *token_mandatory_label = (TOKEN_MANDATORY_LABEL *)buffer; DWORD dw; if (!GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &dw)) { printf("GetTokenInformation: %u\n", GetLastError()); return; } if (!ConvertSidToSsortingngSidA(token_mandatory_label->Label.Sid, &ssortingngsid)) { printf("ConvertSidToSsortingngSid: %u\n", GetLastError()); return; } printf("SID: %s\n", ssortingngsid); } void get_elevation(HANDLE token) { TOKEN_ELEVATION_TYPE elevation; DWORD dw; if (!GetTokenInformation(token, TokenElevationType, &elevation, sizeof(elevation), &dw)) { printf("GetTokenInformation: %u\n", GetLastError()); return; } printf("Elevation type : %u\n", (DWORD)elevation); } void test(void) { HANDLE token1, token2; SID_AND_ATTRIBUTES sids_to_disable; STARTUPINFOA si = {sizeof(STARTUPINFOA)}; PROCESS_INFORMATION pi; if (!OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token1)) { printf("OpenProcessToken: %u\n", GetLastError()); return; } printf("token1:\n"); get_membership(token1); get_integrity(token1); get_elevation(token1); sids_to_disable.Atsortingbutes = 0; sids_to_disable.Sid = admins_sid; if (!CreateRessortingctedToken(token1, DISABLE_MAX_PRIVILEGE, 1, &sids_to_disable, 0, NULL, 0, NULL, &token2)) { printf("CreateRessortingctedToken: %u\n", GetLastError()); return; } printf("token2:\n"); get_membership(token2); get_integrity(token2); get_elevation(token2); if (!CreateProcessAsUserA(token2, NULL, "cmd", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { printf("CreateProcessAsUser: %u\n", GetLastError()); return; } } int main(int argc, char ** argv) { { SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; if(! AllocateAndInitializeSid( &SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &admins_sid) ) { printf( "AllocateAndInitializeSid: %u\n", GetLastError()); return 1; } } test(); return 0; } 

Sortie lorsqu’elle est exécutée à partir d’une invite de commande élevée:

 token1: Administrators group enabled: 1 SID: S-1-16-12288 Elevation type : 2 token2: Administrators group enabled: 0 SID: S-1-16-12288 Elevation type : 2 

Si vous réexécutez l’exemple de code à partir du processus enfant, vous pouvez confirmer que le processus enfant a conservé ces propriétés:

 token1: Administrators group enabled: 0 SID: S-1-16-12288 Elevation type : 2 

Si l’UAC est désactivé, le type d’élévation est TokenElevationTypeDefault mais sinon le résultat est identique:

 token1: Administrators group enabled: 1 SID: S-1-16-12288 Elevation type : 1 token2: Administrators group enabled: 0 SID: S-1-16-12288 Elevation type : 1 

Comme prévu, le jeton limité ressemble à ceci:

 token1: Administrators group enabled: 0 SID: S-1-16-8192 Elevation type : 3 

Ou si vous êtes connecté en tant qu’utilisateur non administrateur, que le contrôle de compte d’utilisateur soit activé ou non:

 token1: Administrators group enabled: 0 SID: S-1-16-8192 Elevation type : 1 

(Tous les tests s’exécutent sur Windows 7 SP1 x64.)