- Domain user has access to a domain joined Windows machine
- Domain user must be able to create a subdirectory under “Datastore\0” which is theoretically no more possible. But as we will see there are at least two method to bypass the limitation.
First Method: “Domain Group Policy” abuse
We will implement a Domain User Group Policy which produces “files”, typically script files such as Logon/Logoff scripts or configuration preferences xml files. This is a very common scenario in AD enterprise domains
Steps to reproduce
- In this case we are going to configure user preferences under “User Configuration\Preferences\Windows Setting” in Group Policy Management. But it’s just an example, logon/logoff scripts will work too.
- On the Domain Controller create a Domain preferences policy (for example “Ini Files”)
- Login with domain user credentials on a domain joined computer
- Check if the “Group Policy Cache” has been saved under the directory:
- C:\programdata\microsoft\GrouPolicy\users\<SID>\Datastore (the entire directory, subdirectories and files are read-only for users after CVE-2020-1317)
- If not, perform a “gpupdate /force” via command prompt
- We can observe that the preference “inifiles.xml” has been created
- Now we will place an exclusive “oplock”  on this file:
- On a new command prompt, we will force a new “gpupdate /force”. Oplock will be triggered and policy processing hangs:
- Here comes the fun part(!), when Group Policy Caching is processed, the “gpsvc” service, running as SYSTEM, lists all the files and folders starting from the local “DataStore” root directory and performs several “SetSecurity” operations on subfolders and files. The first “SetSecurity” will always grant “Full control” to the current user, the second one only read access. This is the first run and we should have full control over the “Datastore” folders. In a new command prompt, we will try to create a directory under “Datastore\0” folder:
- Once created, we disable inheritance and remove permissions to SYSTEM and Administrator Group. Why? Because when we release the “oplock”, the “second run” will occur during which the domain user will be granted read only access. Given that the process is running as SYSTEM, this operation will be denied. This can be observed in following procmon screenshot:
- Now we have a directory with full control where we can place a symlink via \RPC Control to a SYSTEM protected file… and, just as an example, alter the contents of “printconfig.dll”, start an XPS Print job and gain a SYSTEM shell, as described in previous blog posts 
Second Method: redirect Windows Error Processing “ReportQueue” directory
In this case we are going to redirect the “C:\ProgramData\Microsoft\Windows\WER\ReportQueue” folder to the “Datastore\0” directory. This folder is normally empty if no error reporting process is running.
Steps to reproduce
- Create the junction. In this case we are using CreateMountPoint.exe , we can also use the built-in “mklink /j “ command but we need to remove the directory before
- Ensure that optional diagnostics data etc.. has been turned on in Settings->Privacy->Diagnostics&feedback
- Launch “Feedback Hub” and report a problem. Remember to check “Save a local copy…”
- You will observe that the redirected “ReportQueue” directory will be populated. As soon as this happens, perform a “gpupdate /force”
- Once the update has finished, you will be able to create a directory under the “Datastore\0” folder. At this point, you can proceed with same technique explained before
I think to have successfully demonstrated that even after CVE-2020-1317 bug fix, there were still several possibilities to abuse junctions and Set Security calls in group policy client in order to perform an elevation of privilege starting from a low privileged domain user.
That’s all 😉