# HG changeset patch # User Andre Heinecke # Date 1409821255 -7200 # Node ID 6684e5012b7a64e273af642891299b1c9f3014af # Parent 461db8f903f50352b0f585dc91dcbe43044ff02e (issue98) Set integrity level to medium on restricted token and evaluate it to determine if the process is elevated. diff -r 461db8f903f5 -r 6684e5012b7a cinst/nssstore_win.c --- a/cinst/nssstore_win.c Wed Sep 03 15:48:34 2014 +0200 +++ b/cinst/nssstore_win.c Thu Sep 04 11:00:55 2014 +0200 @@ -110,6 +110,12 @@ { SAFER_LEVEL_HANDLE user_level = NULL; HANDLE retval = NULL; + SID_IDENTIFIER_AUTHORITY medium_identifier = {SECURITY_MANDATORY_LABEL_AUTHORITY}; + PSID medium_sid = NULL; + TOKEN_MANDATORY_LABEL integrity_label; + + memset (&integrity_label, 0, sizeof (integrity_label)); + if (!SaferCreateLevel(SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &user_level, NULL)) @@ -124,6 +130,38 @@ return NULL; } + SaferCloseLevel(user_level); + + /* Set the SID to medium it will still be high otherwise. Even if + there is no high access allowed. */ + if (!AllocateAndInitializeSid(&medium_identifier, + 1, + SECURITY_MANDATORY_MEDIUM_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &medium_sid)) + { + PRINTLASTERROR ("Failed to initialize sid.\n"); + return NULL; + } + + integrity_label.Label.Attributes = SE_GROUP_INTEGRITY; + integrity_label.Label.Sid = medium_sid; + + if (!SetTokenInformation(retval, + TokenIntegrityLevel, + &integrity_label, + sizeof(TOKEN_MANDATORY_LABEL))) + { + PRINTLASTERROR ("Failed to set token integrity.\n"); + return NULL; + } + return retval; } diff -r 461db8f903f5 -r 6684e5012b7a common/util.c --- a/common/util.c Wed Sep 03 15:48:34 2014 +0200 +++ b/common/util.c Thu Sep 04 11:00:55 2014 +0200 @@ -406,6 +406,51 @@ #endif bool +has_high_integrity(HANDLE hToken) +{ + PTOKEN_MANDATORY_LABEL integrity_label = NULL; + DWORD integrity_level = 0, + size = 0; + + if (hToken == NULL || hToken == INVALID_HANDLE_VALUE) + { + DEBUGPRINTF ("Invalid parameters."); + return false; + } + + /* Get the required size */ + if (!GetTokenInformation(hToken, TokenIntegrityLevel, + NULL, 0, &size) == ERROR_INSUFFICIENT_BUFFER) + { + PRINTLASTERROR ("Failed to get required size.\n"); + return false; + } + integrity_label = (PTOKEN_MANDATORY_LABEL) LocalAlloc(0, size); + if (integrity_label == NULL) + { + ERRORPRINTF ("Failed to allocate label. \n"); + return false; + } + + if (!GetTokenInformation(hToken, TokenIntegrityLevel, + integrity_label, size, &size)) + { + PRINTLASTERROR ("Failed to get integrity level.\n"); + LocalFree(integrity_label); + return false; + } + + /* Get the last integrity level */ + integrity_level = *GetSidSubAuthority(integrity_label->Label.Sid, + (DWORD)(UCHAR)(*GetSidSubAuthorityCount( + integrity_label->Label.Sid) - 1)); + + LocalFree (integrity_label); + + return integrity_level >= SECURITY_MANDATORY_HIGH_RID; +} + +bool is_elevated() { bool ret = false; @@ -423,6 +468,13 @@ ret = elevation; } } + /* Elevation will be true and ElevationType TokenElevationTypeFull even + if the token is a user token created by SAFER so we additionally + check the integrity level of the token which will only be high in + the real elevated process and medium otherwise. */ + + ret = ret && has_high_integrity (hToken); + if (hToken) CloseHandle (hToken); #endif diff -r 461db8f903f5 -r 6684e5012b7a common/util.h --- a/common/util.h Wed Sep 03 15:48:34 2014 +0200 +++ b/common/util.h Thu Sep 04 11:00:55 2014 +0200 @@ -136,6 +136,17 @@ */ bool create_restricted_directory (LPWSTR path); +/**@briefu Check the integrity level of the token + * + * Returns true if the token has SECURITY_MANADTORY_HIGH_RID or + * SECURITY_MANDATORY_SYSTEM_RID and false otherwise. + * + * @param[in] hToken the Token to check + * + * @returns true if the token has at least high integrity. + */ +bool has_high_integrity(HANDLE hToken); + #endif #ifdef __cplusplus