T1590.003 Microsoft Sentinel · KQL

Detect Network Trust Dependencies in Microsoft Sentinel

Adversaries may gather information about the victim's network trust dependencies that can be used during targeting. This includes identifying second or third-party organizations such as managed service providers (MSPs), contractors, and partner organizations that have privileged or elevated network access to the target environment. Adversaries gather this information through direct elicitation (spear phishing for information), public sources (LinkedIn, company websites, job postings revealing MSP/vendor relationships), WHOIS/DNS records, and Active Directory trust enumeration once they have initial internal access. Internally, this manifests as enumeration of Active Directory domain and forest trusts using built-in tools (nltest.exe, netdom.exe), PowerShell AD cmdlets (Get-ADTrust, Get-ADForest), or LDAP queries targeting trustedDomain objects. Externally, adversaries may discover trust relationships from public BGP routing data, certificate transparency logs, or OSINT tools targeting organizational infrastructure. The intelligence gathered enables attacks via trusted third-party relationships (T1199), supply chain compromise (T1195), or credential abuse against MSP-managed accounts.

MITRE ATT&CK

Tactic
Reconnaissance
Technique
T1590 Gather Victim Network Information
Sub-technique
T1590.003 Network Trust Dependencies
Canonical reference
https://attack.mitre.org/techniques/T1590/003/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let TrustEnumProcesses = dynamic(["nltest.exe", "netdom.exe"]);
let TrustEnumPSPatterns = dynamic([
  "Get-ADTrust", "Get-ADForest", "Get-ADDomain",
  "domain_trusts", "/domain_trusts", "/all_trusts", "/trusted_domains",
  "TRUST_QUERY_INFO", "LSA_TRUSTED_DOMAIN_INFO",
  "NetEnumerateTrustedDomains", "DsEnumerateDomainTrusts",
  "trustedDomain", "trustDirection", "trustAttributes"
]);
let NltestTrustArgs = dynamic([
  "/domain_trusts", "/all_trusts", "/trusted_domains",
  "/dclist", "/dsgetsite", "/parentdomain"
]);
// Branch 1: Direct trust enumeration tools
let ProcessBranch = DeviceProcessEvents
| where Timestamp > ago(24h)
| where (FileName =~ "nltest.exe" and ProcessCommandLine has_any (NltestTrustArgs))
    or (FileName =~ "netdom.exe" and ProcessCommandLine has_any ("trust", "query", "/enumerate_principals"))
    or (FileName in~ ("powershell.exe", "pwsh.exe") and ProcessCommandLine has_any (TrustEnumPSPatterns))
    or (FileName =~ "net.exe" and ProcessCommandLine has "/domain")
    or (FileName =~ "dsquery.exe" and ProcessCommandLine has_any ("trustedDomain", "trust"))
| extend DetectionType = case(
    FileName =~ "nltest.exe", "NltestTrustEnum",
    FileName =~ "netdom.exe", "NetdomTrustEnum",
    FileName in~ ("powershell.exe", "pwsh.exe"), "PowerShellADTrustEnum",
    FileName =~ "net.exe", "NetViewDomainEnum",
    "DsqueryTrustEnum"
  )
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
         InitiatingProcessFileName, InitiatingProcessCommandLine, DetectionType;
// Branch 2: Security Event 4662 — LDAP access to trustedDomain objects
let LDAPBranch = SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4662
| where ObjectType has_any ("trustedDomain", "domainDNS")
| where AccessMask in ("0x100", "0x20000", "0x1") // READ_PROPERTY, CONTROL_ACCESS, READ_GENERAL
| extend DetectionType = "LDAPTrustedDomainAccess"
| project Timestamp=TimeGenerated, DeviceName=Computer, AccountName=SubjectUserName,
         FileName=tostring(""), ProcessCommandLine=ObjectName,
         InitiatingProcessFileName=tostring(""), InitiatingProcessCommandLine=tostring(""),
         DetectionType;
union ProcessBranch, LDAPBranch
| sort by Timestamp desc
medium severity medium confidence

Detects network trust dependency enumeration via two complementary approaches. Branch 1 uses DeviceProcessEvents to identify process-based trust enumeration: nltest.exe with trust-related flags (/domain_trusts, /all_trusts), netdom.exe trust queries, PowerShell cmdlets (Get-ADTrust, Get-ADForest), net.exe domain enumeration, and dsquery.exe targeting trustedDomain objects. Branch 2 uses SecurityEvent 4662 (directory service object access) to detect LDAP-level reads against trustedDomain and domainDNS objects, which catches custom tooling and manual LDAP queries that bypass common process-level detections. Both branches are unioned and sorted chronologically for analyst review.

Data Sources

Process: Process CreationDS0026: Active Directory Object AccessMicrosoft Defender for EndpointMicrosoft Sentinel SecurityEvent (Windows Security Log)

Required Tables

DeviceProcessEventsSecurityEvent

False Positives & Tuning

  • Domain administrators legitimately running nltest.exe /domain_trusts during infrastructure audits or troubleshooting inter-domain authentication issues
  • Automated monitoring scripts using Get-ADTrust or Get-ADForest to verify trust health and alert on unexpected trust additions
  • Identity governance tools (SailPoint, Saviynt, CyberArk) that enumerate domain trusts during discovery scans
  • Microsoft Entra Connect (Azure AD Connect) synchronization service regularly querying forest/domain trust topology
  • IT helpdesk staff troubleshooting cross-domain resource access using netdom.exe or nltest.exe
  • Security posture assessment tools (Bloodhound Enterprise, Purple Knight) authorized to enumerate AD trust relationships
Download portable Sigma rule (.yml)

Other platforms for T1590.003


Testing Methodology

Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Enumerate Domain Trusts via nltest.exe

    Expected signal: Sysmon Event ID 1: Process Create with Image=C:\Windows\System32\nltest.exe, CommandLine='/domain_trusts /all_trusts'. Security Event ID 4688 (with command line auditing): same command line data. Parent process will be cmd.exe or powershell.exe depending on execution context.

  2. Test 2Enumerate Active Directory Trusts via PowerShell Get-ADTrust

    Expected signal: Sysmon Event ID 1: Process Create with Image=powershell.exe, CommandLine containing 'Get-ADTrust'. PowerShell ScriptBlock Log Event ID 4104 with full script content including trust properties being queried. LDAP query to Domain Controller on port 389 for trustedDomain objects (visible in Sysmon Event ID 3 if DC is remote).

  3. Test 3Query AD Forest Trust Information via PowerShell Get-ADForest

    Expected signal: Sysmon Event ID 1: Process Create with Image=powershell.exe, CommandLine containing 'Get-ADForest'. PowerShell ScriptBlock Log Event ID 4104 with the full script. Directory access Event ID 4662 on Domain Controllers for crossRefContainer and crossRef object reads. Sysmon Event ID 3 for LDAP connection to DC on port 389.

  4. Test 4Enumerate Domain Trusts via netdom.exe

    Expected signal: Sysmon Event ID 1: Process Create with Image=C:\Windows\System32\netdom.exe, CommandLine containing 'query' and 'trust'. Security Event ID 4688 (with command line auditing) recording the full command line. The tool will contact the nearest Domain Controller to resolve trust information.

  5. Test 5LDAP Query for trustedDomain Objects via dsquery

    Expected signal: Sysmon Event ID 1: Process Create with Image=C:\Windows\System32\dsquery.exe, CommandLine containing 'trustedDomain'. On the Domain Controller: Security Event ID 4662 with ObjectType=trustedDomain for each trust object read. Multiple 4662 events will fire — one per trusted domain object in the directory.

Unlock Pro Content

Get the full detection package for T1590.003 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections