Vulnerability
Two months ago, I was playing with Cygwin and I noticed that all Cygwin processes inherited dead process handles using Process Hacker:
Bash.exe process spawned by SSH daemon after a successful connection (1) runs with a newly created token as limited test user.
Indeed, Cygwin SSHD worked at the time with an administrator account (cyg_server) emulating set(e)uid by creating a new user token using undocumented NtCreateToken. See Cygwin documentation for more information about the change with version 3.0.
The same bash.exe process inherits 3 handles of non-existent processes with full access rights (2).
Tracing the process creation and termination with Process Monitor during the SSH connection revealed that these leaked handles are actually privileged process (3) running as cyg_server.
Exploitation
So what can we do with privileged zombie process handles, since we have full access (PROCESS_ALL_ACCESS) we can:
Access Right | Possible action |
---|---|
OpenProcessToken | FAIL Access denied |
PROCESS_VM_OPERATION | FAIL: Any VM operation will fail because the process does not have a address space anymore |
PROCESS_CREATE_THREAD | FAIL: Same problem, no address space, creating thread in the process will NOT work |
PROCESS_DUP_HANDLE | FAIL: Access denied on DuplicateHandle (not sure why :D) |
PROCESS_CREATE_PROCESS | SUCCESS: Finally! Let’s see how to use this privilege: |
When creating a process, the attribute PROC_THREAD_ATTRIBUTE_PARENT_PROCESS in STARTUPINFO structure allows the calling process to use a different process as the parent for the process being created. The calling process must have PROCESS_CREATE_PROCESS access right on the process handle used as the parent.
From Windows documentation: Attributes inherited from the specified process include handles, the device map, processor affinity, priority, quotas, the process token, and job object. So the spawned process will use the privileged token thus it will run as cyg_server:
This exploitation technique is not new and there are maybe other ways to exploit this case but I wanted to show a real world example of create process with parent handle instead of just posting about it. I find it cleaner than injecting a shellcode in a privileged process to spawn a process.
Fix
The vulnerability is now fixed with Cygwin version 3.0 thanks to the maintainers that were very responsive.
Commit 1: Restricting permissions