This blog series is aimed at giving security practitioners (both defense & offense ) a thorough understanding of Windows access tokens for detection engineering.
Here in Part 2, we’ll cover key concepts in Windows Security. The desired outcome is to help understand what the access control model is. Access tokens, their types, and how the system uses them. Windows integrity level, DLL files, and finally User access control. Additionally, this blog owes a huge debt of gratitude to all the researchers at Microsoft who constantly put efforts into updating and improving open-source learning.
Access control refers to security features that control who can access resources in the operating system. Applications call access control functions to set who can access specific resources or control access to resources provided by the application.
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. When a user logs on, the system verifies the user’s password by comparing it with information stored in a security database. If the password is authenticated, the system produces an access token. Every process executed on behalf of this user has a copy of this access token.
The system uses an access token to identify the user when a thread interacts with a securable object or tries to perform a system task that requires privileges. 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
TYPES OF TOKENS
- Process Tokens
- Thread tokens
There are two main types of tokens;
- Primary tokens
- Impersonation tokens
All processes in Windows have a primary token associated with them. These dictate the privileges of the associated process. When a new process is created, the default action is for the child process to inherit the primary token associated with its parent.
Windows is a multi-threaded operating system and a process will always have at least one associated thread. By default, a thread will operate under the same security context as its parent process, utilizing the primary token. However, Windows also uses the concept of impersonation, which allows a thread to temporarily impersonate a different security context if given access to a different access token. This is normally performed using impersonation tokens. The most common use of this functionality is to enable application developers to allow the Windows kernel to handle the bulk of access control.
Tokens have different security levels associated with them. These further identify the privilege level that a given token represents. A token can have one of four security levels: –
The security levels with the greatest security implications are Impersonate and Delegate because they can be used to assume a different security context; Anonymous and Identity do not have this ability and are therefore not discussed here. The Impersonate level allows a thread to impersonate the security context of the token on the local system but does not allow access to external systems using that token. However, the Delegate level allows a thread to impersonate the security context of the token on any system because it stores the relevant authentication credentials. The majority of risk exposure through access tokens is a consequence of the presence of Delegate tokens
Under some circumstances, tokens can enable local privilege escalation. This is most likely to occur if an attacker has compromised a low privileged service. Services that allow clients to connect via Windows authentication will normally gain access to an Impersonate token for the client. This would normally be used by the thread serving the client to impersonate the client’s security context. If the connecting client was an administrator then the attacker could use this token to escalate their privileges on the system to gain administrative access. A good example of this would be if an attacker had compromised an instance of Microsoft SQL Server running as a low-privileged service account. If a DBA, who was a local administrator of the system, connected to SQL Server via Windows authentication then the attacker could use his token to gain administrative control of the server.
ACCESS CONTROL LISTS
A security descriptor contains two access control lists (ACLs) used to assign and track security information for each object: the discretionary access control list (DACL) and the system access control list (SACL).
Discretionary access control lists (DACLs). DACLs identify the users and groups that are assigned or denied access permissions on an object. If a DACL does not explicitly identify a user or any groups that a user is a member of, the user will be denied access to that object. By default, a DACL is controlled by the owner of an object or the person who created the object, and it contains access control entries (ACEs) that determine user access to the object.
System access control lists (SACLs). SACLs identify the users and groups that you want to audit when they successfully access or fail to access an object. Auditing is used to monitor events related to system or network security, to identify security breaches, and to determine the extent and location of any damage. By default, a SACL is controlled by the owner of an object or the person who created the object. A SACL contains access control entries (ACEs) that determine whether to record a successful or failed attempt by a user to access an object using given permission, for example, Full Control and Read.
The following illustration shows a DACL that denies access to one user and grants access to two groups. The members of Group A get Read, Write, and Execute access rights by accumulating the rights allowed to Group A and rights allowed to Everyone. The exception is Andrew, who is denied access by the access-denied ACE despite being a member of the Everyone Group.
Mandatory Integrity Control (MIC) provides a mechanism for controlling access to securable objects. This mechanism is in addition to discretionary access control and evaluates access before access checks against an object’s discretionary access control list (DACL) are evaluated.
MIC uses integrity levels and mandatory policy to evaluate access. Security principals and securable objects are assigned integrity levels that determine their levels of protection or access. For example, a principal with a low integrity level cannot write to an object with a medium integrity level, even if that object’s DACL allows write access to the principal.
WINDOWS DANGEROUS PRIVILEGES
Microsoft provides documentation outlining the privilege constants in Windows. These privileges can be assigned directly to a user or inherited via group membership. While many of these privileges can be abused, the following are the most commonly abused privilege constants in malicious software and attacker tradecraft:
Description: This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file.
Attacker Tradecraft: Collection.
Description: Required to create a primary token.
Attacker Tradecraft: Privilege Escalation
Description: Required to debug and adjust the memory of a process owned by another account.
Attacker Tradecraft: Privilege Escalation; Defense Evasion; Credential Access
Description: Required to load or unload a device driver.
Attacker Tradecraft: Persistence; Defense Evasion
Description: Required to perform restore operations. This privilege causes the system to grant all write access control to any file, regardless of the ACL specified for the file.
Attacker Tradecraft: Persistence; Defense Evasion
Description: Required to take ownership of an object without being granted discretionary access.
Attacker Tradecraft: Persistence; Defense Evasion; Collection
Description: This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege.
Attacker Tradecraft: Privilege Escalation
DYNAMIC LINK LIBRARY
A DLL is a library that contains code and data that can be used by more than one program at the same time. For example, in Windows operating systems, the Comdlg32 DLL performs common dialog box related functions. Each program can use the functionality that is contained in this DLL to implement an Open dialog box. It helps promote code reuse and efficient memory usage.
By using a DLL, a program can be modularized into separate components. For example, an accounting program may be sold by module. Each module can be loaded into the main program at run time if that module is installed. Because the modules are separate, the load time of the program is faster. And a module is only loaded when that functionality is requested.
Additionally, updates are easier to apply to each module without affecting other parts of the program. For example, you may have a payroll program, and the tax rates change each year. When these changes are isolated to a DLL, you can apply an update without needing to build or install the whole program again.
Types of DLLs
When you load a DLL in an application, two methods of linking let you call the exported DLL functions. The two methods of linking are −
- load-time dynamic linking, and
- run-time dynamic linking.
Load-time dynamic linking
In load-time dynamic linking, an application makes explicit calls to the exported DLL functions like local functions. To use load-time dynamic linking, provide a header (.h) file and an import library (.lib) file, when you compile and link the application. When you do this, the linker will provide the system with the information that is required to load the DLL and resolve the exported DLL function locations at load time.
Run-time dynamic linking
In runtime dynamic linking, an application calls either the LoadLibrary function or the LoadLibraryEx function to load the DLL at runtime. After the DLL is successfully loaded, you use the GetProcAddress function, to obtain the address of the exported DLL function that you want to call. When you use runtime dynamic linking, you do not need an import library file.
The following list describes the application criteria for choosing between load-time dynamic linking and runtime dynamic linking −
- Startup performance − If the initial startup performance of the application is important, you should use run-time dynamic linking.
- Ease of use − In load-time dynamic linking, the exported DLL functions are like local functions. It helps you call these functions easily.
- Application logic − In runtime dynamic linking, an application can branch to load different modules as required. This is important when you develop multiple-language versions.
HOW DLL FILES WORK
Visualize two different files – “example.exe,” a common executable file, and “library.dll,” a DLL file that is by that executable. How these both files are connected by the operating system when “example.exe” runs?
When “example.exe” runs the OS loads it and locates a table of data within it, affirming that “this program uses the following list of functions from the DLL file library.dll” which is technically known as “imports” or “imported functions” from the DLL “library.dll” in the program “example.exe.”
After that, the loader code looks for “library.dll” and if it locates it, the file gets loaded. Inside these DLL files, there is another list known as “export list”, which joins particular addresses to each of the functions inside the DLL file.
From this point of time, when “example.exe” requires to call a function from “library.dll.” it simply uses that address.
NOTE: Due to a vulnerability commonly known as DLL hijacking, DLL spoofing, DLL preloading, or binary planting, many programs will load and execute a malicious DLL contained in the same folder as a data file opened by these programs. Which we’ll discuss in future posts.
USER ACCESS CONTROL
Each app that requires the administrator access token must prompt for consent. The one exception is the relationship that exists between parent and child processes. Child processes inherit the user’s access token from the parent process. Both the parent and child processes, however, must have the same integrity level. Windows 10 protects processes by marking their integrity levels. Integrity levels are measurements of trust. A “high” integrity application is one that performs tasks that modify system data, such as a disk partitioning application, while a “low” integrity application is one that performs tasks that could potentially compromise the operating system, such as a Web browser. Apps with lower integrity levels cannot modify data in applications with higher integrity levels. When a standard user attempts to run an app that requires an administrator access token, UAC requires that the user provide valid administrator credentials.
In order to better understand how this process happens, let’s look at the Windows logon process.
By default, standard users and administrators access resources and run apps in the security context of standard users. When a user logs on to a computer, the system creates an access token for that user. The access token contains information about the level of access that the user is granted, including specific security identifiers (SIDs) and Windows privileges.
When an administrator logs on, two separate access tokens are created for the user: a standard user access token and an administrator access token. The standard user access token contains the same user-specific information as the administrator access token, but the administrative Windows privileges and SIDs are removed. The standard user access token is used to start apps that do not perform administrative tasks (standard user apps). The standard user access token is then used to display the desktop (explorer.exe). Explorer.exe is the parent process from which all other user-initiated processes inherit their access token. As a result, all apps run as a standard user unless a user provides consent or credentials to approve an app to use a full administrative access token.
A hive is a logical group of keys, subkeys, and values in the registry that has a set of supporting files loaded into memory when the operating system is started or a user logs in.
Each time a new user logs on to a computer, a new hive is created for that user with a separate file for the user profile. This is called the user profile hive. A user’s hive contains specific registry information pertaining to the user’s application settings, desktop, environment, network connections, and printers. User profile hives are located under the HKEY_USERS key.
Registry files have the following two formats: standard and latest. The standard format is the only format supported by Windows 2000. It is also supported by later versions of Windows for backward compatibility. The latest format is supported starting with Windows XP. On versions of Windows that support the latest format, the following hives still use the standard format: HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE\SAM, HKEY_LOCAL_MACHINE\Security, and HKEY_USERS\.DEFAULT; all other hives use the latest format.
Most of the supporting files for the hives are in the %SystemRoot%\System32\Config directory. These files are updated each time a user logs on. The file name extensions of the files in these directories, or in some cases a lack of an extension, indicate the type of data they contain. The following table lists these extensions along with a description of the data in the file.
|none||A complete copy of the hive data.|
|.alt||A backup copy of the critical HKEY_LOCAL_MACHINE\System hive. Only the System key has a .alt file.|
|.log||A transaction log of changes to the keys and value entries in the hive.|
|.sav||A backup copy of a hive.|
Windows Server 2003 and Windows XP/2000: Copies of the hive files as they looked at the end of the text-mode stage in Setup. Setup has two stages: text mode and graphics mode. The hive is copied to a .sav file after the text-mode stage of setup to protect it from errors that might occur if the graphics-mode stage of setup fails. If setup fails during the graphics-mode stage, only the graphics-mode stage is repeated when the computer is restarted; the .sav file is used to restore the hive data.
HKEY_LOCAL_MACHINE, often abbreviated as HKLM, is one of several registry hives that make up the Windows Registry. This particular hive contains the majority of the configuration information for the software you have installed, as well as for the Windows operating system itself. https://5e7ce163cedd8d0d5bb3c127110b7d9d.safeframe.googlesyndication.com/safeframe/1-0-38/html/container.html
In addition to software configuration data, the HKEY_LOCAL_MACHINE hive also contains lots of valuable information about currently detected hardware and device drivers.
In Windows 10, Windows 8, Windows 7, and Windows Vista, information about your computer’s boot configuration is included in this hive, too.
The following registry keys are located under the HKEY_LOCAL_MACHINE hive:
HKEY_CURRENT_USER, often abbreviated as HKCU, is one of a half-dozen or so registry hives, a major part of the Windows Registry.
HKEY_CURRENT_USER contains configuration information for Windows and software specific to the currently logged-in user.
For example, various registry values in various registry keys located under the HKEY_CURRENT_USER hive control user-level settings like the installed printers, desktop wallpaper, display settings, environment variables, keyboard layout, mapped network drives, and more.
Many of the settings you configure within various applets in the Control Panel are actually stored in the HKEY_CURRENT_USER registry hive.
Some common registry keys you might find under the HKEY_CURRENT_USER hive:
- HKEY_CURRENT_USER\Control Panel
- HKEY_CURRENT_USER\Keyboard Layout
- HKEY_CURRENT_USER\Volatile Environment
COMPONENT OBJECT MODEL
COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. COM is the foundation technology for Microsoft’s OLE (compound documents) and ActiveX (Internet-enabled components) technologies. COM objects can be created with a variety of programming languages. Object-oriented languages, such as C++, provide programming mechanisms that simplify the implementation of COM objects. These objects can be within a single process, in other processes, even on remote computers.