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.
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:
If these match, access is granted to the requesting process.
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 asWriteFile
,WaitForSingleObject
,RegQueryValueEx
, etc. Closing a handle: Functions such asCloseHandle
,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
<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.