Select Page

The story of the Trojan Horse is well known to everyone who has taken a history class. True or not, the story goes that the Greeks, in an effort to finally sack the city of Troy, construct a giant wooden horse with some of their top soldiers hidden inside. They wheel the horse up to the gates of Troy and pretend to sail away. The Trojans, thinking they’ve gained some great victory prize, wheel the horse inside their gates, where the waiting soldiers come out at night and open the gates for their comrades, and end the war (badly for Troy, I might add). I thought it was an appropriate way to describe my latest foray into the world of hacking Group Policy.  The analogy to this latest attack is relevant, because in this case, the approach involves creating a malicious and otherwise hidden GPO in a place where you would not expect to find a GPO, and generally invisible to GP management tools. This Trojan GPO nonetheless can be applied to AD-joined computers and users and linked to containers to execute whatever instructions are contained in that GPO.

Where’s the Horse?

The impetus for this attack was my wondering about whether the AD part of a GPO, called the Group Policy Container (GPC) could be hosted somewhere other than it’s default location in an Active Directory domain–which is under CN=Policies,CN=System in a given domain partition. I had already shown that the SYSVOL part of the GPO (called the Group Policy Template or GPT) could be re-directed to any arbitrary SMB share. But I was curious if the same kind of misdirection would work for the AD part. The GPC is, after all, the lynchpin of a GPO. It’s what determines what extensions are implemented in that GPO, whether the GPO has changed since the last time it was processed by a given user or computer, and its DN is used to create a link to it on a given site, domain or OU container object. I started off by creating a GPC from scratch, using ADSIEdit, in just some arbitrary locations in AD, such as under the CN=Keys container:

Creating a GPC object under an arbitrary AD container

Although I could successfully create the GPC object (a GPC object can be created under any container class object in AD) and I could link this “GPO” to a given OU, I could not get the client to successfully process it. I enabled GPSvc logging on the client that processed that GPO to figure out why it failed and got my answer pretty quickly. When the client is in the “core” phase of GP processing, it figures out which GPOs are linked to containers it’s a member of, then it queries AD for the GPC objects of those GPOs. That query looks like this:

GPSVC(5a0.b80) 17:39:40:875 EvaluateDeferredGPOs: Searching for GPOs in cn=policies,cn=system,DC=sdmsoftware,DC=lab
GPSVC(5a0.b80) 17:39:40:875 EvaluateDeferredGPOs: Adding filters (&(!(flags:1.2.840.113556.1.4.803:=2))(gPCMachineExtensionNames=[*])((|(distinguishedName=cn={6A06FDD2-872C-4878-BA17-82EDD9CE9CF2},cn=policies,cn=system,DC=sdmsoftware,DC=lab)(distinguishedName=cn={D167F90F-785A-401A-8E28-F9F2051FA2CC},cn=policies,cn=system,DC=sdmsoftware,DC=lab)(distinguishedName=cn={147C4FCA-AD5D-44AB-AD81-BA5435556612},cn=policies,cn=system,DC=sdmsoftware,DC=lab)(distinguishedName=CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=Policies,CN=System,DC=sdmsoftware,DC=lab)(distinguishedName=cn={260B46D0-AAC2-4914-8363-88B491F43853},cn=policies,cn=system,DC=sdmsoftware,DC=lab)(distinguishedName=cn={0BC734DB-92DB-4A82-8F9D-A38DC37A9D46},cn=policies,cn=system,DC=sdmsoftware,DC=lab)(distinguishedName=CN={a8faf2ea-ed8b-47f6-8e8c-a5b825ee559d},CN=Keys,DC=sdmsoftware,DC=lab))))

What you notice in the first line of the GPSVC log, is that the LDAP search base for the client is always the CN=Policies container. So even though, in the second line, you see the reference to my Trojan GPO under CN=Keys, in the LDAP filter, the client will never find the GPC for that GPO, because it’s not under CN=Policies. Back to the drawing board!

Now Comes the Trojan Part

With this information in hand, I reckoned that the only place it made sense to “hide” my Trojan GPO, was somewhere under CN=Policies. But, if it’s in that container, then it’s really not a Trojan, since all GPOs normally live there anyway, right? Well not so fast, it turns out that each GPC object has two objects of class Container underneath it, like so:

The Machine and User containers under the GPC

The Machine and User containers are created by default when you create a new GPO. Under normal circumstances, they are used, among other things, to host some settings information if you happen to be using Group Policy Software Installation within a GPO. But, because they are container objects, they are a perfect parent to my Trojan GPO. Hiding a GPO inside of a GPO? A tactic that would inspire even Ulysses! With that, I set about creating my Trojan GPO to test.

The advantage of this approach is that I can put a Trojan GPO into any GPO that I have write access to–as long as I can create the GPC object under either the Machine or User container (doesn’t matter which really) . Once there, I can create my Trojan. This means that a regular, run of the mill GPO that is doing nothing related to my Trojan, can house this nefarious GPO.

Creating a GPC object isn’t terribly hard using a tool like ADSIEdit. I just need a GUID, a few properties on the object, and the Machine and User containers underneath it, and an SMB share that can host the GPO’s settings (once again, this can be any SMB share–it doesn’t have to, and probably shouldn’t, live in SYSVOL), and I’m good. In the end, I created my Trojan GPO under the Machine container on an existing GPO that I had write access to, like this:

The Trojan GPO

Once I’ve created my Trojan GPO and populated it’s GPT with some nasty settings (or in my case, just a harmless Admin Template Setting for testing) I need to link it to a container to apply it to clients. Of course, this does require my having write access to the gpLink attribute on a container object in AD, but we know how tightly those are delegated, right? With such access, I can write the link as follows:

[LDAP://cn={260B46D0-AAC2-4914-8363-88B491F43853},cn=policies,cn=system,DC=sdmsoftware,DC=lab;0][LDAP://cn={0BC734DB-92DB-4A82-8F9D-A38DC37A9D46},cn=policies,cn=system,DC=sdmsoftware,DC=lab;0][LDAP://CN={496460a6-c30e-44d1-bafb-2289fc6bd8bf},CN=Machine,CN={62BF8BE9-ADA6-4265-9E37-5A2E09028593},CN=Policies,CN=System,DC=sdmsoftware,DC=lab;0]

where the bolded part is the reference to my Trojan GPO. Once linked, any computer (or user) in the scope of that GPO will process it as normal.

What Happens with GP Management and the Client?

Now, there are a couple of characteristics about Trojan GPOs that are useful to know about. First, they are not visible in GPMC, under the Group Policy Objects container. You just won’t see them, which is good from an attacker’s perspective and obviously, bad from a defender’s perspective. You will see evidence of the linking of a Trojan GPO, but unless you know what you’re looking at, it may not be obvious what it is. As an example, this is how a Trojan GPO link looks on a container object in GPMC:

Viewing the link for a Trojan GPO

As you can see, the link shows the GPO as “Not Found”, which may or may not be useful to an unsuspecting administrator. The only evidence you do get, that a Trojan GPO has been applied somewhere, is that Resultant Set of Policy (RSoP) will dutifully record the malicious GPO and it’s settings just as normal:

RSoP reporting successfully on the Trojan GPO

Defense

Just like those guarding Troy, the best defense against a Trojan GPO is to prevent it from “coming in the gates” in the first place. As with many attacks that I talk about on this blog, I try to include information on what you can do to defend against them. The most obvious thing with this issue, and the thing I always bring up in the case of GP-based attacks, is that delegation matters. You need to control who can link GPOs, and to where, very tightly. And, you need to control who can edit GPOs. If you delegate both linking and editing broadly to many administrators, then each of those administrator accounts, if compromised, becomes a vector for a Trojan GPO (or any number of other different attacks). This particular attack relies on a bad actor having access to write to a given arbitrary GPO. Remember that once a trojan GPO exists, it’s very hard to see it with existing tooling, so it’s important to prevent it by having very tight control over who can edit GPOs. And, if you can’t do that, then have very tight control over who can link GPOs. Link changes can be audited without problem using standard AD security logs.

And speaking of auditing, the creation of a Trojan GPO can also be audited. After all, it’s just a regular AD object creation, albeit in a non-standard place. So if you are looking for new object creation of objects of class groupPolicyContainer, you will be able to detect any non-standard creation events by looking at the DN of the object that gets created, as shown here:

Auditing the Creation of a Trojan GPO

I think the key here is that GP can be made to do things that were never intended. We’ve seen that in many ways over the last few years. It’s important to keep tight control over your delegation and audit for any suspicious changes on both AD and SYSVOL. Hopefully this has been an interesting new approach in “Messing with Group Policy” 🙂

Darren