https://x.com/Mehrshad_13_ ⏱️ 25 minutes
https://www.linkedin.com/in/mehrshad-mollaafzal/ 2024 06 July

While writing practice code for a driver in windows, I discovered a security issue:

It seemed there was a flaw in the DuplicateHandle function. I started investigating this issue and realized that, from the perspective of the operating system and Windows developers, this behavior is logical. Developers must be very careful when using the DuplicateHandle function to prevent the creation of security vulnerabilities that could lead to privilege escalation.

First, I'll provide a general explanation of handle security, followed by a description of the test programs I developed.

General Content

Objects are typically not directly accessible from user-mode; instead, they are directly and unchecked accessible in kernel-mode.

To use objects in user-mode, the system provides us with a handle.

Whenever an object access request occurs in user-mode, the system performs two actions:

  1. the security system must first be sure of each user’s identity.
  2. The Object Manager and security system confirm that the SID matches with the DACL and SACL.

If these match, access is granted to the requesting process.

Handle Relationship with Security Descriptor and DACL

As Keith Brown explains in his article, operations on handles are summarized as follows: Creating/Opening handle: Functions such as CreateFile, CreateMutex, CreateProcess, RegOpenKeyEx, etc. Using a handle: Functions such as WriteFile, WaitForSingleObject, RegQueryValueEx, etc. Closing a handle: Functions such as CloseHandle, RegCloseKey, etc.

When a process requests a handle for an object (by requesting to create/open a handle), the security system first verifies the user's identity using a token. Then, it checks the DACL of the object to see if the user has the necessary permissions as specified by the process flags. (The DACL contains ACEs showing specific permissions for each SID)

Example: As shown in Figure 1, if access is granted to the process, during execution, each time the process uses the handle, no further security checks are performed.

Figure 1

Figure 1

<aside> 💡 Thus, the DACL is only checked at the time of creating/opening the handle and not during its use or closing.

</aside>

Example: When a read request is sent, the system checks the DACL to verify read access. If granted, a valid handle with read access is provided. If a write is needed afterward, the operation will fail with an "access denied" error since the handle was created with read access only. Pay attention that the request is not sent to the system. The request is stopped by the process itself.

Duplicate Handle and Bypass DACL Check