Not sure why Microsoft keep screwing those patches.
Here's details about the bug - https://github.com/klinix5/ProfSvcLPE/blob/main/write-up.docx
PoC - https://github.com/klinix5/ProfSvcLPE/tree/main/DoubleJunctionEoP
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.
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 - https://twitter.com/jonaslyk/status/1301245145568997376?lang=en). 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
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 - https://youtu.be/9rXXfWN0h6A
(Also, looking for some opportunities to study computer science in UK or anywhere else, if you can help reach me out on my twitter.)
(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.
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
2. Removing PsProtectSignerAntimalware-Light Protection
3. Executing arbitrary code in windows defender protection engine
And to be honest that's very design for an antivirus and if I were Microsoft I'll definitely consider fixing this.
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.
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.
(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” 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 :)
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:
- Run the poc and give it the target drive as an argument.
- It will spawn an instance of storage settings.
- Then go to "change were new content is saved" and change it to the target drive.
- Press enter in the poc
- After few seconds the spooler service will have a child process "notepad.exe" running with system privileges.
First of all, why ? it’s because I can, and because I need a job.
In this blog I will be disclosing about 8 0-day vulnerability and all of them are still unknow to the vendors, don’t expect those bugs to be working for more than a week or two cause probably they will release an emergency security patches to fix those bugs.
a. Sandbox Escape
So avast antivirus (any paid version) have a feature called Avast sandbox, this feature allow you to test suspicious file in sandbox. But this sandbox is completely different from any sandbox I know, let’s say windows sandboxed apps are running in a special container and also by applying some mitigation to their tokens (such as: lowering token integrity, applying the create process mitigation…) and other sandboxes actually run a suspicious file in a virtual machine instead so the file will stay completely isolated. But Avast sandbox is something completely different, the sandboxed app run in the OS and with few security mitigation to the sandboxed app token, such as removing some privileges like SeDebugPrivilege, SeShutdownPrivilege… while the token integrity stay the same, while this isn’t enough to make a sandbox. Avast sandbox actually create a virtualized file stream and registry hive almostly identical to the real one, while it also force the sandboxed app to use the virtualized stream by hooking every single WINAPI call ! This sounds cool but also sound impossible, any incomplete hooking could result in sandbox escape.
Btw, the virtualized file stream is located in “C:\avast! sandbox”
While the virtualized registry hive exist in “H****\__avast! Sandbox” and it look like there’s also a virtualized object manager in “\snx-av\”
So normally to make any escape I should read any available write-ups related to avast sandbox escape, and after some research it look like I found something: CVE-2016-4025 and another bug by google project zero.
Nettitude Labs covered a crafted DeviceIoControll call in order to escape from the virtualization, they noticed after using the “Save As” feature in notepad the actual saved file is outside the sandbox (in the real filesystem) and it look like it’s my way to get out
I selected their way by clicking on “Save As” and it don’t seems to be working because the patch has disabled the feature but instead of clicking on “Save As” I clicked in “Print”
By doing that it look like we got another pop-up so normally I clicked print with the default printer “Microsoft XPS Document Writer”
And yup we will have a “Save As” window after clicking on Print
So clicked on Save, I really didn’t expected anything to happen but guess what
The file was spawned outside the virtualized file stream. That’s clearly a sandbox escape.
How ? it seems look like an external process written the file while impersonating notepad’s access token. And luckily since CVE-2020-1337 I was focused on learning the Printer API by reading every single documentation provided by Microsoft, while in other side. James Forshaw published something related to a windows sandbox escape by using the Printer API here.
So I assume we can easily escape from the sandbox if we managed to call the Printer API correctly, so we will begin with OpenPrinter function
And of course we will specify in pPrinterName the default printer that exist on a standard windows installation “Microsoft XPS Document Writer”
Next we will go for StartDocPrinter function which allow us to prepare a document for printing and the third argument looks kinda important
So we will take a look in DOC_INFO_1 struct and there’s some good news
It look like the second member will allow us to specify the actual file name so yeah it’s probably our way out of Avast sandbox.
Then the final result will look like this
Note: The bug was reported to the vendor but they didn’t replied as usual
a. Privilege Escalation
It was a bit hard to find a privilege escalation but after taking some time, here you go Avast, there’s a feature in Avast called “REPAIR APP” after clicking on it, it look like a new child process is being created by Avast Antivirus Engine called “Instup.exe”
Probably there’s something worthy to look there, after attempting to repair the app. In this case we will be using a tool called Process Monitor
And as usual we got something that worth our attention, the instup process look for some non existing directories C:\stage0 and c:\stage1
So what if they exist ?
I created the c:\stage0 directory with a subfile inside it and I took a look on how the instup.exe behave against it and I observed an unexpected behaviour, instead of just deleting or ignoring the file it actually create a hardlink to the file
we can exploit the issue but the issue is that the hardlink have a random name and guessing it at the time of the hardlink we can redirect the creation to an arbitrary location but unluckily the hardlink random name is incredible hard to guess, if we attempted who know how much time it will take so I prefer to not look there instead I started looking somewhere else
In the end of the process of hardlink creation, you can see that both of them has been marked for deletion, probably we can abuse the issue to achieve an arbitrary file deletion bug.
I’ve created an exploit for the issue, the exploit will create a file inside c:\stage0 and will continuously look for the hardlink. When the hardlink is created the poc OpLock it until instup attempt to delete it, then the poc will move the file away and set c:\stage0 into junction to “\RPC CONTROL\” which there we will create a symbolic link to redirect the file deletion to an arbitrary file
Note: This bug wasn’t reported to the vendor.
PoC can be found here
McAfee Total Security
a. Privilege Escalation
I already found bugs on this AV before and got acknowledged by vendor
For CVE-2020-7279 and CVE-2020-7282
CVE-2020-7282 was for an arbitrary file deletion issue in McAfee total protection and CVE-2020-7279 was for self-defence bypass.
The McAfee total security was vulnerable to an arbitrary file deletion, by creating a junction from C:\ProgramData\McAfee\Update to an arbitrary location result in arbitrary file deletion, the security patch was done by enforcing how McAfee total security updater handle reparse point.
But the most important is C:\ProgramData\McAfee\Update is actually protected by the self defence driver, so even an administrator couldn’t create files in this directory. The bypass was done by open the directory for GENERIC_WRITE access and then creating a mount point to the target directory so as soon the updater start it will delete the target directory subcontent.
But now a lot has changed, the directory now has subcontent (previously it was empty by default),
After doing some analysis on how they fixed the self defence bug. Instead of preventing the directory opening (as it was expected) with GENERIC_WRITE they blocked the following control codes FSCTL_SET_REPARSE_POINT and FSCTL_SET_REPARSE_POINT_EX from being called on a protected filesystem component, I expected FSCTL_SET_REPARSE_POINT_EX but no they did a smart move in this case, so if we didn’t bypass the self defence we don’t have any actual impact on the component.
So this is it, this is as far as I can go… or no ?
a. Novel way to bypass the self defence
This method work for all antiviruses which the filesystem filter.
So how does the kernel filter work ?
The filesystem filter restrict the access to the antivirus owned objects, by intercepting the user mode file I/O request, if the request coming from an antivirus component it will be granted, if not it will return access denied.
So as far as I know there’s 2 way to bypass the filter
1. Do a special call so it will be conflicted by what the driver see
2. Request access from a protected component
So the special way was patched in CVE-2020-7279, the option that remain is the second one. How can we do that ?
The majority of the AV’s GUI support file dialog to select something let’s take by example McAfee file shredder which open a file dialog in order to let you choose to pick something
While the file dialog is used to pick files it be weaponized against the AV, to better understand the we need to make an example code, so I had to look for the API provided by Microsoft to do that. Generically apps use either GetOpenFileNameW or IFileDialog interface and since GetOpenFileNameW seems to be a bit deprecated we will focusing in IFileDialog Interface.
So I created a sample code (it look horrible but still doing the job)
After running the code
It look like that the job is being done from the process not from an external process (such as explorer), so technically anything we do is considered to be done as the process.
Hold on, if the things are done by the process. Doesn’t that mean that we can create a folder in a protected location ? Yes we can
c. Weaponizing the self-protection bypass
The CVE-2020-7282 patch was a simple check against reparse points, before managing to delete any directory.
There’s a simple check to be done, if FSCTL_GET_REPARSE_POINT control on a directory return anything except STATUS_NOT_A_REPARSE_POINT the target will removed else the updater will delete the subcontent as
Chaining it together, I’ve an exploit which demonstrate the bug, first a directory in C:\updmgr will be created and then you should manually move it to C:\ProgramData\McAfee\Update an opportunistic lock will trigger the poc to create a reparse point to the target as soon as the AV GUI attempt to move the folder, the poc will set it to reparse point and will lock the moved directory so it will prevent the reparse point deletion.
PoC can be found here
Anyway it look like there’s a feature come with Avira Prime called Avira System Speedup Pro, I can’t still explain why this behaviour exist in Avira System Speedup feature but yeah it exist.
When starting the Avira System Speedup Pro GUI there’s an initialization done by the service “Avira.SystemSpeedup.Service.exe” which is written in C# which make it easier to reverse the service but I reversed the service and things just doesn’t make any sense so I guess it’s better to show process monitor output to understand the issue.
without even checking for reparse point. It’s extremely easy to abuse the issue.
This time instead of writing a c++ PoC I’ll be writing a simpler one as a batch script. The PoC in this case doesn’t need any user interaction, and will delete the targeted directory subcontent.
PoC can be found here
1 Trend Micro Maximum security
I already discovered an issue in trend micro and it was patched in CVE-2020-25775, I literally just found a high severity issue on trend micro. But I was contracted for so I can’t disclose it here.
Moving out, as other AV’s there’s a PC Health Checkup feature, it probably worth our attention.
While browsing trough the component, I noticed that there’s a feature “Clean Privacy Data” feature.
I clicked on MS Edge and cleaned, the output from process monitor was:
And as you see Trend Micro Platinum Host Service is deleting a directory in a user write-able location without proper check against reparse point while running as “NT AUTHORITY\SYSTEM” which is easily abuse-able by a user to delete arbitrary files.
There’s nothing to say more, I created a proof of concept as a batch script after running it expect the target directory subcontent to be deleted.
PoC can be found here
I will using the same technique explained above to bypass the self protection.
While checking for updates, the antivirus look for a non existing directory
Hmmmm, let’s take a look
The pic shown above, show us that Malwarebytes antivirus engine is deleting every subcontent of C:\ProgramData\Malwarebytes\MBAMService\ctlrupdate\test.txt.txt and since there’s no impersonation of the user and literally no proper check against reparse point we can probably abuse that, by creating a directory there and creating a reparse point inside C:\ProgramData\Malwarebytes\MBAMService\ctlrupdate we can redirect the file deletion to an arbitrary location.
The PoC can be found here
The AV which I engaged with the most, about 11 bugs were reported and 3 of them were fixed.
For the moment I will be talking about a bug which I already disclosed here, this PoC will spawn a SYSTEM shell as soon as it succeed, the bug seems to be still existing on Kaspersky Total Security with December 2020 latest security patches, the only issue you will have is the AV will detect the exploit as a malware, you must do some modification to prevent your exploit from being deleting. Let’s I can confirm that the issue still exist.
One more thing
Another issue I discovered in all Kaspersky’s antiviruses which allow arbitrary file overwrite without user interaction. I’ve already reported the bug to Kaspersky but they didn’t gave me a bug bounty
They said that the issue isn’t eligible for bug bounty because the reproduction of the issue is unstable, ain’t gonna lie I gave them a horrible proof of concept but still do the job so I guess it should be rewarded and since they wrote that they gave bounties. I won’t give bugs for free like a foo.
So let’s dive inside the bug, when any user start Mozilla Firefox, Kaspersky write a special in %Firefox_Dir%\defaults\pref while not impersonating the user or not even doing proper links check, if abused correctly it can be used against the AV to trigger arbitrary file overwrite on-demand without user interaction.
A proof of concept is attached implement the issue, I’ve rewritten a new one which will trigger your needs on demand thanks me later.
PoC can be found here
First, if you’re not familiar with windows installer CVE-2020-16902, it’s literally the 6th time I am bypassing the security patch and they still don’t hire security researchers. I will be using the same package as CVE-2020-16902
Microsoft has patched the issues by checking if c:\config.msi exist, if not it will be used to generate rollback directory otherwise if it exist c:\windows\installer\config.msi will be used as a folder to generate rollback files.
A tweet by sandboxescaper mentioned that if a registry key “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders\C:\Config.Msi” existed when the installation begin, the windows installer will use c:\config.msi as a directory rollback files. As an unprivileged user I guess there’s no way to prevent the deletion or create “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders\C:\Config.Msi”
And as usual there’s always something that worth our attention.
When the directory is deleted, there’s an additional check if the directory exist or not. Which is kinda strange, since the RemoveDirectory returned TRUE
I guess there’s no need to make additional checks. I am pretty sure that there’s a bug there, I managed to create the directory as soon the installer delete and this happened
The installer did a check if the directory exist and it return that the directory exist, so the windows installer won’t delete the registry key “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders\C:\Config.Msi” because the directory wasn’t delete.
In the next installation the C:\Config.Msi will be used to save rollback files on it, which can be easily abused (I’ve already done that in CVE-2020-1302 and CVE-2020-16902).
I’ve provided a PoC as c++ project to exploit the issue, it’s a double click to SYSTEM shell, thank me later again.