12/24/2007

Security Mechanism on Microsoft Windows

  When we talked about Security here, we just refer to Access Control, since there are so many aspects about system security(for example, encryption, decryption, authentication and authorization, access control is just part of ahthorization).

   In general, Access Control means what actions someone can do on something. On Windows operating system, it introduces some similar concepts to this statement: something - Objects, someone - Subjects(also referenced as Principal), actions - Operation(Access Mask). There are many more related concepts:ACL, ACE, SACL, DACL, Empty DACL, NULL DACL, Access Token, SD and SID.

  First, let's explain those concepts:

  Object - also called Securable Object, A securable object is an object that can have a security descriptor. All named Windows objects are securable. Some unnamed objects, such as process and thread objects, can have security descriptors too.

  Security Descriptor - (SD) contains the security information associated with a securable object. A security descriptor can include the following security information:
  • Security identifiers (SIDs) for the owner and primary group of an object.
  • A DACL that specifies the access rights allowed or denied to particular users or groups.
  • A SACL that specifies the types of access attempts that generate audit records for the object.
  • A set of control bits that qualify the meaning of a security descriptor or its individual members.
Principal/Subject - refers to the something that will take actions on securable objects.

  Security Identifier - (SID) is a unique value of variable length used to identify a Principal. Each Windows user account has a unique SID issued by an authority, such as a Windows domain controller, and stored in a security database.

  Access Control List - (ACL) is a list of access control entries (ACE). Each ACE in an ACL identifies a Principal and specifies the access rights allowed, denied, or audited for that trustee. The security descriptor for a securable object can contain two types of ACLs: a DACL and a SACL.

  Discretionary Access Control List - (DACL) identifies the trustees that are allowed or denied access to a securable object.

  System Access Control List - (SACL) enables administrators to log attempts to access a secured object.

  Access Control Entry - (ACE) Each ACE controls or monitors access to an object by a specified Principal. All types of ACEs contain the following access control information:
  • A security identifier (SID) that identifies the Principal to which the ACE applies.

  • An access mask that specifies the access rights controlled by the ACE.

  • A flag that indicates the type of ACE.

  • A set of bit flags that determine whether child containers or objects can inherit the ACE from the primary object to which the ACL is attached.
Access Token - An access token is an object that describes the security context of a process or thread. The information in a token includes the identity and privileges of the user account associated with the process or thread. Access tokens contain the following information:
  • The security identifier (SID) for the user's account

  • SIDs for the groups of which the user is a member

  • A logon SID that identifies the current logon session

  • A list of the privileges held by either the user or the user's groups

  • An owner SID

  • The SID for the primary group

  • The default DACL that the system uses when the user creates a securable object without specifying a security descriptor

  • The source of the access token

  • Whether the token is a primary or impersonation token

  • An optional list of restricting SIDs

  • Current impersonation levels

  • Other statistics
One thing need mention is that, ACEs in a DACL is ORDERED. That is to say, the order of the ACEs in a DACL is very important to the final access checking result.


  When you(actually, a process or thread) perform some kind of operations on a securable objects(for example, read/write a text file), what happened about the access control aspect? How does Windows performs the access check process? Here is a list of tasks Windows will to in order to maintain the access control semantic:
  1. Open up your thread token;
  2. Retrieve the SIDs of you and your groups from access token got from step 1;
  3. Obtain the SD of the securable objects;
  4. Get the ACL from the SD;
  5. For each ACE in the DACL, lookup the SID associated with that ACE;
  6. Lookup this SID in the list of SIDs got from step 2.;
  7. If found, check if it is deny or allow ACE, if deny, access check failed;
  8. Compare the ACCESS_MASK in the ACE with your desired ACCESS_MASK, clear bits that matches;
  9. If all bits in your desired ACCESS_MASK are cleared, access check succeeded, you are allowed to do the operations;
  10. If some bits are still set when you have traversed all ACEs, access check failed.

  the Win32 security API accesscheck() will do most of the upper tasks for you.

  All the upper concepts have corresponding entities in the operating system, which are all in binary form. To facility the management of Windows system security, Microsoft invented a string/text format of these entities. This is what we call Security Descriptor Definition Language, the security descriptor definition language (SDDL) defines the string format that the ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor functions use to describe a security descriptor as a text string. The language also defines string elements for describing information in the components of a security descriptor:
  SD String http://msdn.microsoft.com/en-us/library/aa379570(VS.85).aspx
  ACE String http://msdn.microsoft.com/en-us/library/aa374928(VS.85).aspx
  SID String http://msdn.microsoft.com/en-us/library/aa379602(VS.85).aspx
  The string format SD is a null-terminated string with tokens to indicate each of the four main components of a security descriptor: owner (O:), primary group (G:), DACL (D:), and SACL (S:).
O:owner_sidG:group_sidD:dacl_flags(string_ace1)(string_ace2)... (string_acen)S:sacl_flags(string_ace1)(string_ace2)... (string_acen)
  The string format ACE is in the form of: (ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid)
  You can use two useful command line tools from Windows to display and set the ACL of securable objects. They are icacls and cacls. For example, to see the SD of a file - d:\myfile.ext, you can just run "cacls d:\myfile.ext /s". For more information about these to commands, type command /? for help.
  An Excellent Tutorial about Windows Security Mechanism:
  Part 1 - Background and Core Concepts. The Access Control Structures
  Part 2 - Basic Access Control programming
  Part 3 - Access Control programming with .NET v2.0
  Part 4 - The Windows 2000-style Access Control editor

  You may use the upper introduction knowledge when you design/implementation some security editing features in deploy applications to customer desktop or check the access rights of some client users on some securable objects in some enterprise online services. Otherwise, you are not likely to use these dinosaur APIs.
  Things can be learned from the design point of view:
  1. Data Structures (such as Security_Descriptor, ACL, ACE, SID) are not exposed to developers, although it's defined as C/C++ struct in some windows predefined header files. Developers can only access the members of those structures by means of Authorization APIs. It's kind of Encapsulation implemented by C.
  2. Binary form of data is hard for human, while text format is human readable and it will greatly improve the manageability and reduce the possibility to produce errors. Since security involves a lot of human activities(such as security administration), text format representation is definitely helpful.
  3. Compared with traditional unix access control mechanism, Windows access control facility is more powerful, since you can control everyone's access rights. But it's also definitely ugly and complicated. Could we implemented powerful functionalities(like the Windows one) in a simple and elegant way(as in the Unix world)?

No comments: