Friday, 22 October 2021

Windows User Profile Service 0day LPE


Not sure why Microsoft keep screwing those patches.

Here's details about the bug -

PoC -

This bug require another user password that's different from the current one, I'm not sure. But it might be possible to do it without knowing someone else password.
The PoC must be tested with standard user privileges with another standard user password. If it succeeds, it will spawn a SYSTEM shell.

At the time of writing this, this vulnerability affects every server and desktop edition including 11 and server 2022.

Thursday, 2 September 2021

ZDI-21-1053: Bypassing Windows Lock Screen


In April 2021, I discovered a security flaw in Windows Recovery Environment Agent which allowed an unauthenticated attacker to gain elevated access to a windows machine in a locked state.

Those research were based on Jonas findings related to bypassing lockscreen (you can find more here - He described a flaw, which allowed lock screen bypass using Ease of Access feature.

Looking at CVE-2020-1398, the bug existed in sticky keys pop-up 

By clicking the link, an instance of settings will be spawned in the background. Then you’ll be simply able to bypass the lockscreen. Microsoft has patched the issue by removing the link as it no longer appears when being spawned in a lockscreen environment.

And to be clear this bug and its descendants need a condition. On Windows 10 machine, at least one user must have a Microsoft account linked to his local account. Otherwise, the bug isn't exploitable.

Now, I'll try to give a short explanation for you humans. Cause if I showed the video PoC you will be confused as hell.

As you can see above, Windows can allow you to reset your password/pin if you had access to your Microsoft account. If you click on "I forgot my PIN" you will be redirected to something like this

I have noticed a weird kind of behaviour when typing a wrong password, a small arrow next to the email address will be visible.
This behaviour exists for some unknown reason, maybe a bug ? feature ? probably a bug.(apparently its a feature after the patch)

Clicking there will take us to another page.As we can see that we’re allowed to login with another email address or even creating a new account.

I tried to create a new account, login with it but it fails since the account doesn’t belong to the one we are trying to reset its password.

However, this small button right there attracted my attention and hmmm it's interesting

By clicking on it we’ll see another pop-up dialogue, that has a link on it.

Hmmm very interesting, a link ? in the lockscreen ? weird right. As usual, we’ll click on it and see what happen… clicking on it did absolutely nothing, BUT maybe something was spawned in the background and we can’t see it, as Jonas described in his lockscreen bypass, he used to enable narrator in order to navigate in background apps. I enabled narrator and got some very interesting results.

When enabled and I click on the button, you can hear narrator saying “how do you want to open this”, and narrator’s focus is on something else not in Microsoft account window. We spawned an “Open With” window with narrator’s focus on it in the background; Typically the “Open With” window looks like this

But only has two options the first is MS Edge and the second one is Internet explorer, we’ll dig with MS Edge since it’s selected by default, please NOTE that you might to HOLD Caps lock while using arrow keys to navigate.

After tests, as soon as we select OK we lose narrator’s focus and we’re no longer able to control background window.

We can have narrator’s focus again as soon as we repeat steps described above, we’ll have narrator’s focus again. But this time we’ll have it on MS Edge browser, at this point, we will need to elevate our privileges, the only way I can think of to execute arbitrary commands is to spawn a settings instance. This can be done by spawning another a new InPrivate window, (please NOTE: you won’t be able to see any of those, and things will be completely invisible you must use your ear to hear what narrator say and use it to navigate);

Then you might need to go on “More details”

Press enter and navigate to settings

Which will redirect us to another page, keep navigating until you reach “Windows Diagnostic data setting” and then navigate using narrator to open and click enter again

In settings navigate to “Home” and press enter

Then navigate to “Devices”

Navigate to Autoplay->Choose Autoplay Defaults->”Open folder to view files(File explorer)

At this point, you might need to plug a USB device into the device. As soon as plugged narrator will have his focus on file explorer, now you can execute anything in the USB.
In order to verify our findings, I made a simple batch script which will verify our findings

mkdir c:\poc
whoami /all >  c:\poc\whoami.log

And after the execution, we can observe a success

Elevating privileges is easy since we’re marked as “NT AUTHORITY\Authenticated Users” as the majority of EoPs are reachable from those privileges.

PoC -

(Also, looking for some opportunities to study computer science in UK or anywhere else, if you can help reach me out on my twitter.)

Tuesday, 17 August 2021

Shutting Down Anti-malware Protection (Part 1) - Windows Defender Antivirus

(click for better images quality)

I always wanted to start this series, executing code inside antiviruses security agents. 

People always underestimated Ring 3 code execution, as it seems to be useless in case of a cyber attack. The AV agents usually defeat the malware before it starts doing serious damage, unlike being in ring 0, attackers just override callbacks and hooks and proceed to do whatever they want.

 However, those hooks were never made to block trusted agents actions. So in the majority of cases, executing code in the context of an antivirus agent will bypass the hooks.

I'll first of all start with windows defender, it's technically the easiest one. In order to achieve the objective of executing code in the context of the antivirus service "MsMpEng.exe" we will need the following things as a requirement.

1. Figure out a way to shut down or terminate windows defender process without rebooting.
2. Bypass or Disable the PsProtectedSignerAntimalware-Light protection set on the process
3. Have a HANDLE to the process with full access or at least figure out a way to inject a dll in the process.

1. Shutting down windows defender antivirus

Supposing that we already got ring 3 code execution it wouldn't be so hard, there's even a step-by-step description on how to do it here.
And as described, we first of all need a trusted installer token. Easy task, it can be either done by stealing it from trustedinstaller process or create the token using LogonUserExExW.or NtCreateToken... Since
I also had to investigate why this happening despite of it being mentioned by Forshaw in his ticket, there's also another reason for that.
I noticed that the service ACL doesn't allow the SYSTEM user and Administrators group from modifying or stopping windows defender service at all. But it instead allows WinDefend and TrustedInstaller to do that, so technically kidnapping a trustedinstaller token and stopping the service as a ring 3 process won't be that hard.
So I used the following steps to stop windows defender process.
 1. Impersonate a trusted installer token.
 2. Now you can either open the process itself or the service for termination.
And apparently, it worked flawlessly! 

2. Removing PsProtectSignerAntimalware-Light Protection

A quick background about "protection"
Protect processes first appeared in windows vista as a reinforcement for critical windows user-mode services and evolved later as Protect Process Light (PPL) in windows 8.1 and it sounds quite powerful. 
Of course, Microsoft staff aren't idiots, they won't give this powerful primitive to anyone so they can just abuse it to launch your own protected processes. In order to launch a PPL process, your executable must be signed with a special certificate and then it can be possibly done.
After too much research on how to do remove PPL protection from windows defender, it was literally near my eyes but I didn't see it.
According to Microsoft documentation ChangeServiceConfig2W, it's possible to change the service protection as long as you got enough access to the service object. For now, we already got a full access handle to windows defender service from the previous step.
And simply I just called ChangeServiceConfig2W and restarted the service worked perfectly fine.

You can see in process explorer that windows defender is running without PsProtectedSignerAntimalware-Light which makes the next step easier!

3. Executing arbitrary code in windows defender protection engine

This was the most challenging problem, Microsoft actually did a great job protecting the process even if PsProtectSignerAntimalware-Light was disabled.
Classic process injection techniques didn't work as expected, cause windows defender kernel-mode driver kicks in. This feature is also known as "Tamper-Protection" which prevents any unattended injections to any user-mode windows defender service.
And unfortunately, I had to move to DLL hijack bugs to get this done. Shame...
I run into an issue, actually, Microsoft implemented a hard to bypass mitigation ProcessSignaturePolicy which was a serious challenge. So in conclusion we can't inject code nor inject DLLs nor hijack antimalware executables (such as DLLs).
Unfortunately, Microsoft allowed a little flaw there. As trustedinstaller or any process with SeRestorePrivelege enabled we're allowed to have write access to C:\ProgramData\Microsoft\Windows Defender\Platform <- this folder contains windows defender executable with some DLLs. I noticed through reverse engineering that the ProcessSignaturePolicy isn't enabled till all windefend dlls are loaded. Which means if we get a DLL loaded at the process initialization we can have arbitrary code execution inside windows defender process. I also noticed that there's a tiny flaw in the dll load behaviour.
Before windows defender load dlls, it attempts to verify the integrity of the file using WinVerifyTrusted, I noticed a tiny flaw in this functionality.
As soon as Windows defender start it will query 
C:\ProgramData\Microsoft\Windows Defender\Platform for folders and will determine the working directory based on string version, let's take by example the directory query returns the following result
Windows Defender in this case will use 4.18.2108.2-0 which is the latest version.
In this case, windows defender will verify the authenticity of MpSvc.dll and MpClient.dll
I noticed through some R.E that if WinVerifyTrusted returned a failure value, then MpSvc.dll will be immediately loaded from the previous version string

And to be honest that's very design for an antivirus and if I were Microsoft I'll definitely consider fixing this.
Side note, I had another barrier. Creating files in 
%ProgramData%\Microsoft\Windows Defender\Platform wasn't that easy as I thought,
WdFilter.sys is a kernel-mode mini-filter driver made to specifically protect windows defender files. A the same flaw that allowed windows defender service shutdown will also allow us to unload the driver, as the fs driver doesn't seems to be having any "special" Error control, so if it was shut down. Windows won't bsod and will continue to function normally therefore we will be allowed to drop arbitrary binaries in %ProgramData%\Microsoft\Windows Defender\Platform

So in summary, the following steps can be taken to load a malicious dll in windows defender antivirus.

1. Capture a TrustedInstaller token and impersonate it.
2. Stop the AV and remove the PsProtectSignerAntimalware-Light from the service using ChangeServiceConfig2W.
3. Create 
%ProgramData%\Microsoft\Windows Defender\Platform\10.18.3009.5-0\MpSvc.dll (mpsvc.dll must be a directory so we can cause WinVerifyTrust to fail)
4. Drop our malicious dll in 
%ProgramData%\Microsoft\Windows Defender\Platform\8.18.3009.5-0
5. Start WinDefend using StartService
6. Encrypt the users files and force them to pay the ransom.
7. If they paid, make sure to decrypt them, enjoy and repeat!

You can find a small Proof of concept here

[UPDATE]: I forgot to mention the environment, this series will be tested on windows 10 21H1 which is the latest official shipping windows in August 2021.

I'll be covering another AV in part 2, stay tuned!

Thursday, 24 June 2021

CVE-2021-24084 An unpatched information disclosure in Microsoft Windows


The Timeline:

This bug was initially recognized in October 2020, and has been report to Zero Day Initiative Program.
The bug has been reported to Microsoft 2020/10/27 by Zero Day Initiative, the bug was acknowledged and a security advisory has been released as CVE-2021-24084.
In patch Tuesday I tried to see the changes introduced the original code and I was shocked, nothing has changed even if I installed the update that said it was fixing the bug.
I reached out with ZDI and they confirmed they were able to reproduce the indicated behavior without any minimal changes to the original PoC. After few days, I received an update from ZDI and said that Microsoft will release a final patch in April 2021 update.
April arrived and the bug is still unpatched, I reached out with ZDI. And after a long calm, ZDI reached me out with an update and said that they had a meeting with the Principal Program Manager of MSRC, and said that the issue is clearly acknowledged and is under active investigation and is not being left as a joke. And said that a final patch will be released in July (maybe in 2022 lmao)..

The Bug:

I discovered this bug while looking for some options to link my pc with my school account, so if they send or did something I'll know about it. Something attracted me, I saw this tiny text allowing you to export management log

I knew it's some COM shitty things, I didn't had time to implement the entire thing so I just clicked the button.

I clicked it and start process monitor and I saw some very interesting but not useful operations.
The service that host those operations is known as Device Management Enrollment Service or "DmEnrollmentSvc"
And one of the loaded modules was "MdmDiagnostics.dll" and apparently it had a vulnerability.
When requesting the log files to be exported to "C:\Users\Public\Documents\MDMDiagnostics\" a lot of file operations happens in C:\Windows\Temp, and the most interesting ones were "C:\Windows\Temp\DeviceHash_DESKTOP-1VX69Y8.csv"and "C:\Windows\Temp\TpmHliInfo_Output.txt" since they were created and removed without impersonation.
I noticed that they were also copied to C:\ProgramData\Microsoft\MdmDiagnostics and packed as a cab file to C:\Users\Public\Documents\MDMDiagnostics.
The function that handled the copy exist in "MdmDiagnostics.dll" as MdmLogCollector::CollectFileEntry and for some unknown reasons it literally enumerate the file as a directory, and copy it to be packed as a cab file without impersonating the caller.
And redirecting the file copy was literally so easy by just creating a mount point there

The fact that this can be patched by a child by just impersonating the caller is strange, how a multi billion company can't patch a simple bug in 90 days.

PoC can be a single powershell line to create a mount point in "C:\Windows\Temp\DeviceHash_DESKTOP-1VX69Y8.csv" and then starting the log export from settings, it can be easily emulated by calling the COM methods manually so do it yourself.
It can be found here.

Monday, 8 March 2021

Google Update Service being a scum


So recently I've doing some research in google omaha updater, I created some mini tools to communicate with service and to do some tasks. What I've noticed that google omaha is looking for a non existing configuration file "C:\GoogleUpdate.ini" which got my interest. The file seems to be used mainly for logging/debugging detail as described here, and since the service run as a privileged component and accessible to non-admin guys it might be an interesting area to do research with.

A lot of you will say that "C:\" doesn't allow users by default to create new files there, but starting from windows 10 2009 it seems to be allowing authenticated users to write there by default and some DACL changes was done there, the following images were taken from a default windows installation.

And as you can see in windows 10 2009 authenticated users are now allowed to create file in the root directory, which in this case allow us to create "C:\GoogleUpdate.ini" as a standard user.

If you're asking about windows server, no the C:\ doesn't allow non admin to create files there.

Looking at the log configuration file it looks a bit interesting, the parameter "LogFilePath" seems to be interesting and as far as I can see it allow us to specify the log file.

You can guess we already got our arbitrary file overwrite there but does it stop here ? Unfortunately no, looking again at the structure of the there's a "MaxLogFileSize" parameter that take a file size and it can be 0. Looking at the implementation there's a DACL write every time google omaha tries to create a new file allowing "authenticated users" to have write access according to this code snippet.

Now the only thing that remain is starting the service itself, it's easy since I used to do that when I was writing some google omaha tools, you can just call CoCreateInstance and make sure to pass google updater CLSID and hurrai the service started as system.

I written a simple PoC that demonstrate file take over for both google update service and Microsoft Edge Update Service it can be found here.

My twitter.

Friday, 12 February 2021

Windows Installer File Read 0day

 (Click to enlarge)

Days ago, as usual I was reading some google project zero bugs. Then I found this one by James Forshaw about an EoP in dos device when a privileged process impersonate the user to load libraries. You can read the article here , My only problem was the PoC file as it seems look like james submitted 2 attachment to MSRC, the first one was with the actual PoC compiled and a dll, the second attachment seems to be password protected

And after some research trying to find the original PoC source code, I didn't found something useful so the only way to answer my questions is to reverse the actual PoC.

I really had some questions like, how did he managed the override the original link ? how did he get the login session \Sessions\0\DosDevices\X-Y <- how did he manage to get those numbers ?

Nothing special the dll will just call "RevertToSelf()" and then create notepad as a child process.

But for the actual PoC, some ops are done. I will only cover the code which has impact on our research area.

The PoC will first check the current OS architecture if it match x86 it will continue otherwise it will exit. I still don't know why did he do that but maybe to get ride off the annoying Wow64 redirections.

And after doing some reverse I finally answered my question, in order to get the current DosDevice path is to call GetTokenInformation

Then simply it will redirect the dos device symlink to the PoC's current directory by calling NtCreateSymbolicLinkObject, of course it make sure to recreate C:\Windows\System32 and place the dll described previously to system32 with the name PrintFilterPipelinePrxy.dll, after that the PoC will simply call "OpenPrinterW" "StartDocPrinterW" "EndDocPrinter" then the dll will be loaded as the spooler service. Microsoft has released the advisory for the bug as CVE-2015-1644


After taking a look on how Microsoft patched the bug, Microsoft implemented a mitigation to make sure that the dll load behaviour won't be redirected because of a DosDevice link, by using the OBJ_IGNORE_IMPERSONATED_DEVICEMAP. But any other file system operation will follow the link if it’s not using the flag described above.

The following Diagram will explain how things are done

Quite easy, but is it exploitable ? Well yes but actually no. In some rare cases the CreateFileW redirection might be useful. For now I just wanna fix one problem, I didn't like how the PoC call GetTokenInformation to get the current process Dos Device so I've done some research and got some good result.

You won't need to create the actual DosDevice link, overriding C:\ will do the job for the current user.

I was firstly inspired by sandbox escaper arbitrary file read PoC, which was dropped as a 0day vulnerability 2018. The bug existed in MsiAdvertiseProduct function, calling it will trigger a file copy from windows installer service running as SYSTEM privileges.

In this vulnerability I will be attacking the MsiInstallProduct which takes two arguments. 

The first one is szPackagePath which can be either an URL or a local file. The second parameter is szCommandLine.

After calling the function, I had the following output from process monitor

Phase 1: Windows installer service will impersonate the user and call OpenAndValidateMsiStorageRec which will first check if the package valid.

Phase 2: Windows installer service will reverse to itself and create a new file in C:\Windows\Installer\*.msi

Phase 3: It will make sure that the opened file match the expected file to be opened by calling GetFinalPathNameByHandleW if it match the file will be copied if it doesn’t the installer service will impersonate the user and try to copy the file.

The flaw exist exactly in msi.dll!CopyTempDatabase() when it call   CElevate::CElevate((CElevate *)&X, 1); to elevate privileges instead of staying in impersonation mode

There’s some checks in CopyTempDatabase such as CMsiFileCopy::VerifySource which check the source if it valid for for copy or not but it can be defeated if the user impersonation is done incorrectly.

Since the package sanitization will run while impersonating the user, we can redirect it with the trick mentioned above to a valid package which will trick OpenAndValidateMsiStorage and mark it as a valid package. Then the installer will check if the target file is the one expected to be opened in our case yes it is so it will proceed copying the file to C:\Windodws\Installer\*.msi

I succeeded implementing the exploit but I had one more issue, when the file is copied to C:\Windows\installer it’s probably not the only file there so fetching the newly created file is like a programming quiz, I took a while to see my options, the first one was ReadDirectoryChangesW which wait and fetch any newly created file, this sounds great but wasn’t useful. Since windows installer service tamper with certain parameters of the directory and remove the newly created MSI package as soon as it’s written. The second option was to use FindFirstFileW, FindNextFileW which has solved a bit of the problem, the technique I used here is to find newest file created and pick it as the our target, for some unknow reasons the technique failed and always pick the wrong file. So I moved away to another technique (and it was my last hope), This snippet of code will explain the process of finding the newly created file

We will first begin by deprecating “C:\” path and we will use the windows GUI path so we won’t issues with redirection, to retrieve the GUI path of drive you can use GetVolumeNameForVolumeMountPoint, then it will be used primary in the next api calls. Next our PoC will search \Windows\Installer\*.msi and will store it in an array “first_srch[10000]” and then you might notice there’s two calls of FindFirstChangeNotification and according to Microsoft documentation

“Creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree. The function does not report changes to the specified directory itself. “

The PoC will set 2 events, one for the file creation and the second one for file write, When the first event trigger the PoC will restart the search of MSI files and will store to an array, the PoC will take those arrays and compare every file name if there’s something that doesn’t match at certain index then it’s the newly created file. After that we will just wait the second event to trigger then simply copy our file.

How exploitable a windows read-file ?

When windows crash it automatically generate a windows kernel memory dump in C:\Windows\memory.dmp and restrict it’s DACL to administrators only

You can read the file with the PoC :)

The PoC can be found here

[Update] : Fixed as CVE-2021-28437

Saturday, 23 January 2021

Another Privilege Escalation in windows... but this time no one care


I recently discovered a bench of bugs windows appx, I've reported some of them and even some of them were considered as useless since this one require at least 2 active partitions to work so it's kinda an uncommon attack scenario. So instead of keeping them in my pc for no reason or reporting them to msrc I will drop them here.

Steps to reproduce:

  1. Run the poc and give it the target drive as an argument.
  2. It will spawn an instance of storage settings.
  3. Then go to "change were new content is saved" and change it to the target drive.
  4. Press enter in the poc
  5. After few seconds the spooler service will have a child process "notepad.exe" running with system privileges.
You can find an explanation for the issue here.


PoC can be found here