T1597.001 Microsoft Sentinel · KQL

Detect Threat Intel Vendors in Microsoft Sentinel

Adversaries may search private threat intelligence vendor data for information that can be used during targeting. Threat intelligence vendors offer paid feeds, APIs, and portals containing richer contextual data than publicly reported sources — including breach trends, victim industry attribution, successful TTPs, countermeasures, and named threat actor profiles. Adversaries may register accounts under false pretenses, use stolen credentials, or leverage legitimate existing subscriptions to query vendor platforms such as Recorded Future, Mandiant Advantage, CrowdStrike Falcon Intelligence, IBM X-Force Exchange, VirusTotal Intelligence, Shodan, and similar services. The gathered intelligence informs more targeted intrusion campaigns by revealing defensive gaps, preferred targets in a sector, and previously successful attack chains. Detection is extremely difficult because adversary activity occurs entirely on third-party platforms outside the victim organization's telemetry boundary. Victim-side detection relies on anomalous access patterns to SSO-connected TI platforms, API key misuse, and downstream behavioral indicators resulting from the intelligence gathered.

MITRE ATT&CK

Tactic
Reconnaissance
Technique
T1597 Search Closed Sources
Sub-technique
T1597.001 Threat Intel Vendors
Canonical reference
https://attack.mitre.org/techniques/T1597/001/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let ThreatIntelVendorDomains = dynamic([
  "recordedfuture.com", "api.recordedfuture.com",
  "virustotal.com", "api.virustotal.com",
  "shodan.io", "api.shodan.io",
  "falcon.crowdstrike.com", "crowdstrike.com",
  "threatconnect.com", "api.threatconnect.com",
  "anomali.com", "lookslike.anomali.com",
  "intelligence.mandiant.com", "advantage.mandiant.com",
  "exchange.xforce.ibmcloud.com", "ibmxforce.com",
  "talosintelligence.com",
  "otx.alienvault.com",
  "cyberint.com", "flare.systems", "flare.io",
  "pulsedive.com", "greynoise.io", "api.greynoise.io",
  "threatfox.abuse.ch", "urlhaus.abuse.ch"
]);
let SuspiciousUserAgents = dynamic([
  "curl", "python-requests", "python-urllib", "Go-http-client",
  "wget", "libwww-perl", "httpie", "axios", "okhttp"
]);
let LookbackDays = 7d;
// Branch 1: Proxy/firewall logs showing bulk or scripted TI vendor API access
CommonSecurityLog
| where TimeGenerated > ago(LookbackDays)
| where RequestURL has_any (ThreatIntelVendorDomains)
     or DestinationHostName has_any (ThreatIntelVendorDomains)
| extend IsAPICall = RequestURL has_any ("/api/", "/v1/", "/v2/", "/v3/", "apikey=", "api_key=", "?key=")
| extend IsScriptedClient = UserAgent has_any (SuspiciousUserAgents)
| extend VendorQueried = DestinationHostName
| project TimeGenerated, SourceIP, SourceUserName, DestinationHostName,
          RequestURL, RequestMethod, UserAgent,
          IsAPICall, IsScriptedClient, VendorQueried,
          DeviceVendor, DeviceProduct
| sort by TimeGenerated desc
| union (
// Branch 2: Azure AD / Entra ID sign-in anomalies to TI vendor apps
  SigninLogs
  | where TimeGenerated > ago(LookbackDays)
  | where AppDisplayName has_any ("Recorded Future", "CrowdStrike", "VirusTotal",
                                   "ThreatConnect", "Anomali", "Mandiant",
                                   "IBM X-Force", "Shodan")
  | where ResultType == 0  // Successful sign-in
  | extend IsAnomalousLocation = tostring(LocationDetails.city) !in ("")
  | extend CountryCode = tostring(LocationDetails.countryOrRegion)
  | extend SignInRisk = RiskLevelDuringSignIn
  | where SignInRisk in ("high", "medium")
       or NetworkLocationDetails has "anonymizedIPAddress"
       or NetworkLocationDetails has "maliciousIPAddress"
  | project TimeGenerated, UserPrincipalName, AppDisplayName,
            IPAddress, CountryCode, SignInRisk,
            NetworkLocationDetails, ConditionalAccessStatus
  | extend VendorQueried = AppDisplayName,
           IsAPICall = false,
           IsScriptedClient = false
)
| sort by TimeGenerated desc
medium severity low confidence

Dual-branch detection for T1597.001 Threat Intel Vendor reconnaissance. Branch 1 analyzes proxy/firewall CommonSecurityLog entries for bulk or scripted access to known threat intelligence vendor APIs and portals, flagging programmatic user agents and API endpoint patterns that suggest automated bulk querying beyond normal analyst behavior. Branch 2 monitors Azure AD SigninLogs for risky or anomalous successful authentications to TI vendor applications connected via SSO, which may indicate stolen credentials being used to access victim organization's threat intel subscriptions. Both branches are low confidence due to the PRE-attack nature of this technique.

Data Sources

Network Traffic: Network Traffic ContentApplication Log: Application Log ContentLogon Session: Logon Session CreationCommonSecurityLog (proxy/firewall)SigninLogs (Azure AD / Entra ID)

Required Tables

CommonSecurityLogSigninLogs

False Positives & Tuning

  • Security analysts performing routine threat intelligence lookups against vendor APIs during incident investigations
  • SOAR/XSOAR playbooks and automated enrichment pipelines (e.g., Cortex, Splunk SOAR) making programmatic API calls to TI vendors using service account credentials
  • Threat intelligence platforms (TIPs) like MISP, OpenCTI, or ThreatConnect ingesting feeds via scheduled API jobs
  • Vulnerability management or red team tooling querying Shodan or VirusTotal for asset discovery
  • DevSecOps pipelines querying VirusTotal or similar for file hash validation during CI/CD build processes
Download portable Sigma rule (.yml)

Other platforms for T1597.001


Testing Methodology

Validate this detection against 4 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 1VirusTotal Public API Reconnaissance Query

    Expected signal: Proxy/web gateway logs: outbound HTTP GET to api.virustotal.com with URI paths /api/v3/domains/ and /api/v3/ip_addresses/. User-Agent: curl/<version>. Sysmon Event ID 3 (Network Connection) if running on a monitored endpoint: DestinationHostName=www.virustotal.com, DestinationPort=443. DNS query (Sysmon Event ID 22) for virustotal.com.

  2. Test 2Shodan API Infrastructure Scan Query

    Expected signal: Proxy logs: outbound HTTPS GET requests to api.shodan.io with paths /shodan/host/search and /api-info. URI query strings containing key= (API key parameter), query= (search terms). User-Agent: curl. DNS resolution of api.shodan.io. Sysmon Event ID 3 (Network Connection): DestinationHostName=api.shodan.io, DestinationPort=443.

  3. Test 3Python Script Bulk TI Vendor Query Simulation

    Expected signal: Sysmon Event ID 3 (Network Connection): multiple outbound connections to virustotal.com, greynoise.io, otx.alienvault.com, pulsedive.com on port 443. InitiatingProcessFileName=python3. DNS resolution events (Sysmon Event ID 22) for each TI vendor domain. Proxy logs: HTTP GET requests from python-requests User-Agent to multiple TI vendor APIs within a short time window.

  4. Test 4Recorded Future API Key Enumeration (Credential Exposure Test)

    Expected signal: Sysmon Event ID 3 (Network Connection): outbound connections from powershell.exe to api.recordedfuture.com and www.virustotal.com on port 443. Sysmon Event ID 22 (DNS Query): DNS lookups for api.recordedfuture.com, www.virustotal.com. Sysmon Event ID 1 (Process Create): PowerShell execution with Invoke-WebRequest in command line. PowerShell ScriptBlock Log Event ID 4104: full script including API endpoint URLs. Proxy/firewall logs: HTTPS CONNECT to api.recordedfuture.com with python-requests User-Agent.

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections