Security Attributes
Security attributes are fundamental components of the Windows security model, defining the security characteristics of securable objects within the operating system. They are integral to the access control mechanisms that protect system resources from unauthorized access.
Overview
Each securable object in Windows, such as processes, threads, files, registry keys, and more, can have an associated security descriptor. The security descriptor contains information about the object's security, including its owner, primary group, and a Discretionary Access Control List (DACL). Security attributes, in the context of an object's security descriptor, are primarily represented by the components that determine who can access the object and what kind of access they are allowed.
Key Components of Security Attributes (within a Security Descriptor)
- Owner SID: Identifies the user account or group that owns the object. The owner typically has the authority to change the object's permissions.
- Primary Group SID: Identifies the primary group associated with the object. This is less commonly used in modern Windows security but is retained for compatibility.
- DACL (Discretionary Access Control List): This is the most critical part of an object's security attributes. It contains a list of Access Control Entries (ACEs) that specify which users or groups are granted or denied specific access rights to the object.
- SACL (System Access Control List): Defines the auditing settings for the object. It specifies which access attempts (successful or failed) should be logged in the security event log.
Discretionary Access Control Lists (DACLs)
DACLs are the primary mechanism for discretionary access control. They determine whether a security principal (user or group) is allowed or denied access to an object.
Access Control Entries (ACEs)
A DACL is composed of one or more ACEs. Each ACE contains:
- Access Mask: A bitmask specifying the access rights granted or denied. This includes standard access rights (e.g., read, write, execute) and specific rights defined by the object type.
- ACE Type: Indicates whether the ACE grants access (e.g.,
ACCESS_ALLOWED_ACE_TYPE
) or denies access (e.g.,ACCESS_DENIED_ACE_TYPE
). - Flags: Optional flags that can modify the inheritance behavior of the ACE.
- Trustee SID: The Security Identifier (SID) of the user or group to which the ACE applies.
When an access request is made to an object, the system traverses the ACEs in the object's DACL. The order of ACEs is significant:
- Access is denied if a
ACCESS_DENIED_ACE_TYPE
matches the requesting principal and access mask. - Access is granted if an
ACCESS_ALLOWED_ACE_TYPE
matches the requesting principal and access mask, and no precedingACCESS_DENIED_ACE_TYPE
explicitly denies access. - If no ACEs match the requesting principal and access mask, access is implicitly denied.
System Access Control Lists (SACLs)
SACLs are used for auditing access to objects. They specify which system access events should be recorded.
- ACE Type: Indicates whether the ACE specifies auditing for successful accesses (
SYSTEM_AUDIT_ACE_TYPE
) or failed accesses (SYSTEM_AUDIT_FAILURE_ACE_TYPE
). - Access Mask: Specifies the access rights for which auditing should occur.
- Trustee SID: The SID of the user or group whose access attempts are to be audited.
Programmatic Access
Developers can interact with security attributes and security descriptors using Windows API functions such as:
CreateSecurityDescriptor
SetSecurityDescriptorOwner
AddAccessAllowedAce
AddAccessDeniedAce
GetSecurityDescriptorDacl
SetKernelObjectSecurity
GetKernelObjectSecurity
Example: Creating a Security Descriptor
// Pseudocode example
HANDLE hToken;
PSECURITY_DESCRIPTOR pSD = NULL;
PSECURITY_ATTRIBUTES pSA = NULL; // Security Attributes structure
// Initialize security attributes structure
pSA = (PSECURITY_ATTRIBUTES)malloc(sizeof(SECURITY_ATTRIBUTES));
if (pSA == NULL) {
// Handle allocation error
return;
}
pSA->nLength = sizeof(SECURITY_ATTRIBUTES);
pSA->lpSecurityDescriptor = NULL; // Will be set below
pSA->bInheritHandle = FALSE;
// Create a new security descriptor
if (InitializeSecurityDescriptor(&pSD) &&
SetSecurityDescriptorOwner(pSD, &ownerSID, NULL) &&
SetSecurityDescriptorGroup(pSD, &groupSID, NULL) &&
AddAccessAllowedAce(pSD, ACL_REVISION, GENERIC_READ, &userSID)) {
// Security descriptor creation and population successful
pSA->lpSecurityDescriptor = pSD;
// Use pSA when creating a securable object (e.g., CreateFile, CreateProcess)
} else {
// Handle errors
if (pSD) FreeSecurityDescriptor(pSD);
free(pSA);
pSA = NULL;
}
// ... later, when done with pSD ...
if (pSD) FreeSecurityDescriptor(pSD);
if (pSA) free(pSA);
Conclusion
Security attributes, embodied in security descriptors and their constituent DACLs and SACLs, are the cornerstone of object security in Windows. They provide a flexible and granular mechanism for controlling access to system resources and auditing security-relevant events.