Fingerprinting Microsoft Defender for Identity Before You Attack
Hook
Microsoft publishes enough tenant configuration data through public endpoints that attackers can map your security posture before sending a single phishing email. One of the most valuable signals? Whether you're running Microsoft Defender for Identity.
Context
When penetration testers or red teams engage a Microsoft 365 environment, the first question isn't "what credentials can we compromise?" but rather "what are we walking into?" Modern security assessments require understanding the defensive landscape before launching attacks. Microsoft Defender for Identity (MDI), formerly Azure ATP, monitors on-premises Active Directory signals and can detect suspicious authentication patterns, lateral movement, and credential theft in real-time. Knowing whether MDI is deployed fundamentally changes attack strategy—it's the difference between confidently attempting Kerberoasting and expecting immediate detection.
The challenge is that traditional reconnaissance techniques require authenticated access or internal network positioning. You can't exactly ask the security team "hey, are you running MDI?" during the scoping call. This is where check_mdi enters: it exploits the fact that Microsoft's tenant discovery infrastructure leaks configuration details through publicly accessible endpoints. By querying the same APIs that legitimate Microsoft services use for tenant validation and service discovery, the tool reveals whether a target organization has deployed MDI—all without authentication, credentials, or raising alerts. It's OSINT in the truest sense, using information that organizations don't realize they're broadcasting.
Technical Insight
The architecture of check_mdi is deceptively simple, which is precisely why it works. The tool chains together three HTTP requests to different Microsoft endpoints, each revealing a layer of tenant configuration. First, it validates domain ownership in Microsoft 365 by querying the GetCredentialType API endpoint used by Microsoft's login flows. This returns JSON indicating whether the domain is managed (synchronized from on-premises AD) or federated (using external identity providers like ADFS). Second, it extracts tenant metadata including the tenant name and tenant ID from the OpenID configuration endpoint. Third, and most importantly, it checks for MDI by attempting to resolve a predictable hostname pattern that MDI instances use.
The MDI detection mechanism leverages a fascinating implementation detail: when organizations deploy Microsoft Defender for Identity, Microsoft provisions a dedicated sensor workspace with a predictable naming convention. The tool constructs a hostname in the format <tenantname>.atp.azure.com and attempts DNS resolution. If the hostname resolves, it indicates an MDI deployment. This isn't fuzzing or brute forcing—it's exploiting the predictable infrastructure patterns in Microsoft's cloud architecture.
Here's the core enumeration workflow:
import requests
import dns.resolver
def check_domain(domain):
# Step 1: Validate M365 domain ownership
cred_url = "https://login.microsoftonline.com/common/GetCredentialType"
payload = {"Username": f"user@{domain}"}
response = requests.post(cred_url, json=payload)
data = response.json()
if data.get('IfExistsResult') != 0:
print(f"[-] Domain {domain} not found in M365")
return
# Step 2: Extract tenant name from federation metadata
tenant_name = data.get('FederationBrandName')
print(f"[+] Tenant Name: {tenant_name}")
# Step 3: Check for MDI deployment
mdi_hostname = f"{tenant_name}.atp.azure.com"
try:
answers = dns.resolver.resolve(mdi_hostname, 'A')
print(f"[+] MDI DETECTED: {mdi_hostname} resolves")
for rdata in answers:
print(f" IP: {rdata.address}")
except dns.resolver.NXDOMAIN:
print(f"[-] No MDI instance detected")
The elegance lies in what the tool doesn't do. It doesn't attempt to authenticate, doesn't trigger rate limiting by making hundreds of requests, and doesn't touch any endpoints that would generate security logs in the target tenant. The GetCredentialType endpoint is hit thousands of times per second by legitimate login attempts globally—one more query disappears into the noise. The DNS lookup is even quieter, querying public DNS infrastructure that the target organization doesn't control or monitor.
What makes this particularly powerful for red teams is the asymmetric information advantage it provides. Traditional security tools focus on detecting malicious activity after it starts—failed login attempts, unusual authentication patterns, suspicious PowerShell execution. But check_mdi operates entirely in the pre-attack phase, gathering intelligence that shapes attack selection. If MDI is present, smart attackers avoid techniques that generate on-premises AD anomalies. If MDI is absent, the attack surface expands significantly. It's the digital equivalent of casing a building before attempting entry.
The tool also reveals federation configurations, which have their own security implications. Federated domains using ADFS or third-party identity providers present different attack vectors than cloud-managed domains. An attacker discovering ADFS federation might pivot to targeting the ADFS infrastructure directly, bypassing cloud protections entirely. Meanwhile, managed domains indicate password hash synchronization, suggesting that compromising on-premises AD credentials grants cloud access.
One implementation detail worth noting: the script uses the tenant name extracted from GetCredentialType responses rather than requiring users to guess naming conventions. Microsoft's tenant names don't always match domain names—organizations might use "contoso" as their tenant name but own "contoso-corp.com" as their domain. By extracting the canonical tenant name from Microsoft's own responses, check_mdi eliminates guesswork and false negatives.
Gotcha
The fundamental limitation of check_mdi is its reliance on Microsoft's current endpoint behavior and naming conventions. There's no formal API contract guaranteeing that GetCredentialType will continue returning tenant metadata, or that MDI instances will maintain the current hostname pattern. Microsoft could modify these endpoints tomorrow, deprecate the information disclosure, or randomize MDI hostnames—any of which would break detection capabilities. This isn't theoretical; Microsoft has historically locked down endpoints as enumeration techniques became public. The tool works today, but building critical workflows around it means accepting brittleness.
The single-domain limitation creates practical friction during real engagements. Organizations often own dozens or hundreds of domains—subsidiaries, acquisitions, regional variants, legacy domains. Running check_mdi requires manually iterating through each domain without batch processing, parallel execution, or result aggregation. For red team infrastructure or security research requiring scale, you'll need to wrapper the script or choose alternatives with built-in bulk capabilities. Additionally, MDI detection only confirms that Microsoft provisioned an instance—it can't validate whether sensors are actually deployed, properly configured, or actively monitoring. An organization might have paid for MDI but never completed deployment, or deployed sensors only on a subset of domain controllers. The external reconnaissance approach provides a binary yes/no that doesn't capture deployment quality or coverage.
Verdict
Use if: You're conducting time-boxed penetration tests or red team engagements against M365 environments and need quick, quiet tenant profiling during reconnaissance. It's perfect for security researchers building target profiles, purple teams validating detection coverage, or consultants performing pre-engagement scoping. The tool excels in scenarios where you need one piece of critical information—MDI presence—without complex setup or noisy enumeration. Skip if: You need comprehensive M365 enumeration beyond MDI detection (use AADInternals instead), require batch processing for multiple domains (o365creeper handles bulk operations better), or need guaranteed reliability for production security tooling (the endpoint dependencies make it too fragile for critical workflows). Also skip if you're performing authenticated internal assessments where you can query MDI configuration directly through PowerShell or Azure APIs—this tool's value is specifically in unauthenticated external reconnaissance.