changeset 1029:6684e5012b7a

(issue98) Set integrity level to medium on restricted token and evaluate it to determine if the process is elevated.
author Andre Heinecke <andre.heinecke@intevation.de>
date Thu, 04 Sep 2014 11:00:55 +0200
parents 461db8f903f5
children 76cae27b5d83
files cinst/nssstore_win.c common/util.c common/util.h
diffstat 3 files changed, 101 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
 
--- 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
--- 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

http://wald.intevation.org/projects/trustbridge/