Every Security Alert Was Quiet — But the Threat Intelligence Wasn’t
The SOC dashboard was calm. No active incidents. No urgent alerts. A rare and beautiful moment.
Then a new threat intelligence report arrived with an IP address, a domain and a warning: these indicators had been associated with a recent intrusion campaign.
“Wonderful,” Agent Foskett muttered. “Now we get to investigate what didn’t alert.”
Had the environment never encountered the indicators — or had the evidence been sitting quietly in the logs?

The Silent Threat Intelligence Hunt
A newly published indicator can justify a retrospective search. It cannot, by itself, establish an intrusion.
A silent dashboard and an uncomfortable question
Fictional training scenario: On 20 October, a threat intelligence advisory described infrastructure associated with credential theft and command-and-control activity. The report supplied a suspicious IP address, a domain, and a relevant activity period. The organisation’s Microsoft Sentinel incident queue showed nothing.
“No incidents,” said the analyst. “Excellent,” said Agent Foskett. “Now show me the evidence that nothing happened.”
They first checked the advisory’s provenance, confidence, indicator type, first/last-seen dates and whether the indicators were still considered active. A single IP address can be shared, reassigned or used by legitimate services; a domain may appear in passive DNS or benign lookups. The hunt would distinguish indicator match, potential exposure and confirmed malicious activity.
Why threat intelligence and detection are different
Threat intelligence describes potentially relevant adversary infrastructure or behaviour. An analytics rule generates an alert only when its logic, scheduling, data availability and thresholds line up. A quiet incident queue therefore does not mean historical telemetry is clean.
Agent Foskett checked connector health, ingestion delays, retention, analytic rule scope, rule suppression and whether the relevant log sources were collected at all. A retrospective hunt can find evidence that was not previously alertable — or reveal that there is insufficient telemetry to decide.
Reconstruct the case timeline
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
08:10 New threat intelligence advisory received (illustrative) 08:25 Indicator provenance and active window verified 08:40 Sentinel incident queue checked: no related incidents 09:05 Historical firewall and sign-in data queried 09:22 A candidate IP match identified in network telemetry 09:35 Asset owner and connection direction checked 10:10 Further host and identity evidence requested 11:00 Outcome documented: suspicious match, not yet confirmed intrusion
1. Validate indicators in the Sentinel threat intelligence table
ThreatIntelIndicators table is populated. Column availability varies with the TI ingestion path and schema version. Example IP/domain are documentation placeholders; substitute validated indicators.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
let lookback = 30d;
ThreatIntelIndicators
| where TimeGenerated >= ago(lookback)
| where IsActive == true
| where ObservableValue in~ ("203.0.113.45", "update-check.example")
| project TimeGenerated, ObservableValue, ObservableKey,
Confidence, ValidUntil, Description, SourceSystem
| order by TimeGenerated desc2. Look for historical network connections
CommonSecurityLog. A matching source or destination IP is a lead, not proof of command-and-control. Confirm NAT, direction and whether traffic was allowed.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
let suspectIP = "203.0.113.45";
CommonSecurityLog
| where TimeGenerated > ago(30d)
| where DestinationIP == suspectIP or SourceIP == suspectIP
| project TimeGenerated, DeviceVendor, DeviceProduct,
SourceIP, DestinationIP, DestinationPort,
DeviceAction, Protocol, Computer
| order by TimeGenerated asc3. Check sign-ins for an indicator IP
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
let suspectIP = "203.0.113.45";
SigninLogs
| where TimeGenerated > ago(30d)
| where IPAddress == suspectIP
| project TimeGenerated, UserPrincipalName, AppDisplayName,
IPAddress, ResultType, ResultDescription,
ConditionalAccessStatus, CorrelationId
| order by TimeGenerated asc4. Expand from the candidate host and assess repetition
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 9
- 10
let suspectIP = "203.0.113.45";
CommonSecurityLog
| where TimeGenerated > ago(30d)
| where DestinationIP == suspectIP
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated),
Connections=count(), Ports=make_set(DestinationPort, 20),
Actions=make_set(DeviceAction, 20)
by SourceIP, DeviceVendor, DeviceProduct
| order by Connections desc5. Review DNS requests when DNS telemetry is available
DnsEvents table is present and populated in the workspace; otherwise query your actual DNS connector table and adapt field names. A lookup is not equivalent to a completed connection.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
let suspectDomain = "update-check.example";
DnsEvents
| where TimeGenerated > ago(30d)
| where Name =~ suspectDomain or Name endswith strcat(".", suspectDomain)
| project TimeGenerated, Computer, ClientIP, Name,
QueryType, IPAddresses
| order by TimeGenerated asc6. Correlate candidate sign-ins with account activity
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
let suspectIP = "203.0.113.45";
let matchedUsers =
SigninLogs
| where TimeGenerated > ago(14d) and IPAddress == suspectIP
| distinct UserPrincipalName;
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName in (matchedUsers)
| summarize Signins=count(), IPs=make_set(IPAddress, 30),
Apps=make_set(AppDisplayName, 30),
Failures=countif(ResultType != 0)
by UserPrincipalName
| order by Signins descWhat the logs did — and did not — prove
In this fictional case, a firewall record showed an internal device attempting an outbound connection to the reported IP. The record’s action required interpretation: an attempted or blocked connection is not evidence of a successful session. No corresponding identity match appeared in the available sign-in data.
The team preserved the candidate events, verified whether the IP was in use during the advisory’s reported timeframe, checked the asset’s role, and requested endpoint telemetry to determine whether a process initiated the connection. Without process-level and network-session context, the correct conclusion remained potential indicator overlap requiring investigation, not “confirmed breach.”
The six-stage investigation
- Validate the intelligence: provenance, confidence, indicator freshness and relevant campaign timeframe.
- Validate visibility: connectors, ingestion, retention and analytic rule coverage.
- Hunt retrospectively: search network, DNS and identity telemetry using the appropriate schema.
- Enrich the matches: asset ownership, traffic direction, action, NAT and known benign explanations.
- Correlate independent evidence: endpoint process trees, authentication details and repeated behaviours.
- Decide and document: confirmed incident, suspicious activity needing escalation, benign match or insufficient evidence.
What the organisation should do next
For a credible high-risk match, preserve the raw events and promptly follow the organisation’s incident-response process. Validate endpoint evidence and consider proportionate containment based on confidence and impact. Update detections only after testing for false positives; use watchlists or TI analytics carefully, and review whether relevant log sources and retention meet the hunting requirement.
Where no matches appear, report “no matches in the data searched” with the specific time window and log sources — not “the organisation was never exposed.”
Investigation findings
Case outcome: The retrospective hunt identified one network indicator overlap, but the available evidence did not establish successful attacker access. The team opened a follow-up investigation, documented the visibility limitations and added a reviewed detection path for the indicator family.
Agent Foskett had a final question: “If the dashboard is quiet, have we checked whether it was listening?”
Related Agent Foskett investigations
Final thought
Agent Foskett closed the incident dashboard. Still green. Still quiet.
“There,” he said. “Nothing to worry about.”
Then he opened the threat intelligence hunt results again.
“Actually, I’d prefer to check the logs before congratulating the dashboard.”
The logs already knew. The alert queue just hadn’t been asked the right question.

