October 26, 2026
From Medium Integrity to SYSTEM on Windows 11
My October 26 lab test and the MSRC outcome
By Nathansb
6 min read
On October 26, 2026, I recorded a Windows 11 lab run that started in a medium-integrity PowerShell session and ended with a session running as NT AUTHORITY\SYSTEM. Process Explorer was open on the Windows machine, and an Ubuntu VM was hosting the test files and waiting for the connection.
I had submitted this research to the Microsoft Security Response Center a few months earlier. MSRC determined that it did not meet its vulnerability criteria. The screenshots here are from the October 26 run.
Credit for the way around UAC goes to the LOLBAS project. I used its documented ComputerDefaults technique and the entry acknowledges Eron Clarke.
The Windows VM was on 25H2, build 26200.9711. My account already belonged to the local Administrators group, though the PowerShell session I started from had a filtered token and was running at medium integrity.
Before launching anything, I checked that token. BUILTIN\Administrators was marked Group used for deny only, and the mandatory label was Medium Mandatory Level, SID S-1โ16โ8192.
The starting PowerShell process was PID 1876, with a start time of 3:49:53 PM. Sysmon and WinDefend were running. Defender reported Normal mode, with antivirus, real-time protection, and tamper protection enabled.
A separate administrator PowerShell session handled the monitoring setup. I checked the Sysmon configuration there and marked the beginning of the test at 3:55:41 PM. The original medium-integrity session was the one used to launch the test.
The Ubuntu VM had address 10.0.2.15 and was serving files from its Documents directory. This capture includes the date output, 3:56:03 PM, and the running file server.
By the next Ubuntu capture, at 3:56:35 PM, both test files were in place and the listener was waiting on port 89.
gatpoc.txt contains C# wrapped in PowerShell. The other file, e.txt, is the PowerShell reverse shell used for the lab connection.
Back in the original PowerShell session, I fetched the hosted test file with Invoke-RestMethod and passed it to Invoke-Expression. The first stage used ComputerDefaults and the per-user ms-settings command handler:
HKCU\Software\Classes\ms-settings\Shell\Open\commandHKCU\Software\Classes\ms-settings\Shell\Open\commandThe loop opened a registry transaction, wrote the test command, committed the transaction, and launched ComputerDefaults. In my MSRC submission, I described a possible timing window around that sequence. The transaction-specific explanation is something I still need to distinguish from the documented UAC technique.
Defender started flagging the activity almost immediately. Its first detection in the marked window is timestamped 3:58:21 PM and named Behavior:Win32/UACBypassExp.T!gen. Other detections reference ComputerDefaults. At 05:14 in the recording, the Windows Security notification is visible.
Process Explorer filled with ComputerDefaults instances, high-integrity PowerShell processes, and compiler activity. CPU usage climbed, and SYSTEM command processes appeared in the list. The exported timeline contains 180 ComputerDefaults process creations and 63 high-integrity PowerShell processes whose recorded parent was ComputerDefaults. Those counts belong to this one capture.
The next part of the test involved repeated NtQuerySystemInformation and NtQueryInformationToken calls while other threads changed state concurrently. My report proposed a token-validation race affecting access to winlogon.exe. The event logs let me check the resulting activity without relying on that explanation alone.
Sysmon captured 63 PowerShell-to-winlogon access events with GrantedAccess set to 0x1fffff. There were also 63 remote-thread events into winlogon, with KERNEL32.DLL!WinExec identified as the start function. The process timeline shows 63 cmd.exe processes running as NT AUTHORITY\SYSTEM, with winlogon.exe as their recorded parent.
The Ubuntu listener received a connection. Checking the identity in that session returned nt authority\system. The full output includes SID S-1โ5โ18 and System Mandatory Level, SID S-1โ16โ16384.
Defender eventually killed the original PowerShell launcher. Sysmon records PID 1876 ending at 4:00:08 PM. For this run, I needed multiple PowerShell sessions in parallel so the timing-dependent attempts could finish while Defender was terminating sessions. That accounts for the number of PowerShell and ComputerDefaults processes in the capture.
In the connected session, I checked the date and process ID. Windows returned Monday, October 26, 2026, 4:00:49 PM, and echo $PID returned 552. I could now match the session to a specific process on the Windows machine.
Process Explorer showed PID 552 beneath cmd.exe PID 13248, which was beneath winlogon.exe PID 800. The PowerShell process was a grandchild of winlogon, with cmd.exe in between.
winlogon.exe PID 800
cmd.exe PID 13248
powershell.exe PID 552winlogon.exe PID 800
cmd.exe PID 13248
powershell.exe PID 552
Opening the properties for PowerShell PID 552 confirmed the parent as cmd.exe (13248) and the user as NT AUTHORITY\SYSTEM. Its start time was 3:59:24 PM, matching the process I was checking from the Ubuntu session.
I checked the process GUIDs as well as the PIDs when matching the processes. Windows had already used PID 552 for a different process earlier in the run, so its start time and parent relationship mattered too.
Defender detected activity and reported remediation during the same run.
There is still a question about what caused the access to be granted. A handle to a SYSTEM process doesn't change the caller's identity, and Microsoft's OpenProcess documentation explains how enabled SeDebugPrivilege affects access checks. The SYSTEM session is supported by the capture. Proving the token-validation race I proposed would also mean accounting for the caller's existing privileges and ruling out other explanations.
The registry side needs more work too. Launching an elevated child after a transaction doesn't establish that ComputerDefaults read uncommitted registry data. The capture shows the execution sequence and the resulting identities, while the transaction-specific cause remains unconfirmed.
Microsoft's Windows security servicing criteria put UAC in the defense-in-depth category and explain the trusted position of administrative processes. I've linked that policy for context. MSRC's response to my submission was that it did not meet the vulnerability criteria; I haven't attributed a more specific reason to that decision.
By the end of the run, I could match the SYSTEM session received on Ubuntu to PowerShell PID 552 in Process Explorer and follow its parents back to winlogon. The proposed timing behavior still needs closer investigation, but that final check gives me a concrete result to build on. I can now point to the process, its identity, and where it sits in the tree.
Edit โ October 27, 2026: I went back through the script and saved Sysmon records to follow the original PowerShell session through to the SYSTEM session shown above. That gives me a clearer account of what happened, even though the access-check question is still open.
In this run, the first stage was a timing competition with Defender. The test repeatedly registered and triggered the command while Defender detected activity and terminated processes. Once it had elevated execution, the embedded C# attempted to open winlogon, allocated memory inside it, and wrote a command string into that memory. It then created a remote thread starting at WinExec to launch the command in winlogon's context. That led to the SYSTEM process chain shown in the screenshots.
Matching the process GUIDs gives me the following sequence from the original medium-integrity PowerShell to the final SYSTEM PowerShell. The sideways arrow marks the remote-thread activity into an existing process:
PowerShell 1876 [Medium]
โโ ComputerDefaults 15104 [High]
โโ PowerShell 15196 [High]
โโ remote thread โ winlogon 800 [SYSTEM]
โโ cmd 13248 [SYSTEM]
โโ PowerShell 552 [SYSTEM]PowerShell 1876 [Medium]
โโ ComputerDefaults 15104 [High]
โโ PowerShell 15196 [High]
โโ remote thread โ winlogon 800 [SYSTEM]
โโ cmd 13248 [SYSTEM]
โโ PowerShell 552 [SYSTEM]Sysmon records PowerShell 15196 accessing winlogon 800 with GrantedAccess 0x1fffff at 3:59:00.845 PM. At 3:59:10.858 PM, it records that same PowerShell creating the remote thread. One millisecond later, winlogon creates SYSTEM cmd 13248, which starts SYSTEM PowerShell 552 at 3:59:24.758 PM. Those are local times on October 26. The timing strongly connects the remote thread to the command shell, although Sysmon does not directly identify which winlogon thread created that child.
I also looked at CVE-2024โ30088, a token-query race in NtQueryInformationToken that allows escalation to SYSTEM. My test uses NtQueryInformationToken too, but I have not established that it uses the same vulnerability. What I can now follow is the path from my original session, through the elevated process and winlogon activity, to the SYSTEM session I received on Ubuntu.