[SEC://RESEARCH]_

SIEM · SOAR · Threat Detection

← ~/BLOG

2025-10-25 // Dylan Evans

Why Smart SOC Teams Are Rethinking Sentinel Ingestion (And What They're Doing Instead)

SOC teams face tough decisions about which logs to ingest into Sentinel given volume-based costs. With Microsoft introducing USOP, security teams should lean more on Advanced Hunting and Custom Alert Rules within Defender XDR to reduce costs while maintaining detection coverage.

Microsoft SentinelDefender XDRDetection EngineeringSOCKQLSIEM

SECOPs and SOC teams are faced with the choice of how to best collect, analyse and engineer security data, often with cost considerations in terms of what logs to ingest and what to leave out. With Microsoft introducing USOP, security teams should learn to lean more on the capabilities of Advanced Hunting and Custom Alert Rules within Defender XDR.

Advantages of Defender XDR Detections

The most immediate advantage of using custom alert rules within Microsoft Defender XDR (Defender from here) is the potential cost-saving. Sentinel costing is based on the volume of ingested logs. For important, and high-volume, tables like DeviceEvents or IdentityLogonEvents, ingesting these to create analytic rules is simply not feasible.

In comes USOP within Defender XDR. Maintain 30 days' worth of logs (more than enough time to generate an alert for a specific event) at no additional cost, while still generating alerts and sending these into your preferred SIEM/Incident Response platform. For organisations ingesting large tables like the ones mentioned, the costs can escalate extremely quickly, and value might not be seen if the logs are not queried frequently.

It is important to note that Defender XDR does not natively support raw third-party log ingestion. Sentinel (or another SIEM/SOAR platform) is still required to fill that gap. Defender XDR is designed for detection and response, not for log retention, parsing, or analytics, which is why a third-party platform is needed to handle non-native log ingestion.

Engineering Detections within Defender XDR

We'll use the following detection rule as an example (GitHub / detections.ai):

// Title: Suspicious AI activity related to PromptLock Ransomware Activity
// Description: Detects activity related to the PromptLock ransomware, which leverages the Ollama AI API
//              and is written in Go. This rule looks for network connections to the Ollama service and
//              related process executions.
// Author: Dylan Evans (detections.ai/user/Decksy), https://github.com/dylanevans-cybersec/KQL-Queries
// References: https://x.com/ESETresearch/status/1960365364300087724

let timeframe = 24h;
let ollama_port = 11434;
let common_tools = dynamic(["go.exe", "curl.exe", "wget.exe", "python.exe", "python3.exe", "powershell.exe", "pwsh.exe"]);
let suspicious_events = union isfuzzy=true
(DeviceNetworkEvents
| where Timestamp >= ago(timeframe)
| where RemotePort == ollama_port and InitiatingProcessFileName in~ (common_tools)
| extend UserAgent = tostring(parse_json(AdditionalFields).UserAgent)
| project Timestamp, DeviceId, DeviceName, AccountName = InitiatingProcessAccountName,
    ProcessName = InitiatingProcessFileName, ProcessCommandLine = InitiatingProcessCommandLine,
    RemoteIP, RemotePort, RemoteUrl, UserAgent, ActivityType = "NetworkToOllamaPort"
),
(DeviceNetworkEvents
| where Timestamp >= ago(timeframe)
| where RemoteUrl contains "ollama"
| extend UserAgent = tostring(parse_json(AdditionalFields).UserAgent)
| where UserAgent contains "go-http-client"
| project Timestamp, DeviceId, DeviceName, AccountName = InitiatingProcessAccountName,
    ProcessName = InitiatingProcessFileName, ProcessCommandLine = InitiatingProcessCommandLine,
    RemoteIP, RemotePort, RemoteUrl, UserAgent, ActivityType = "GoClientToOllamaUrl"
),
(DeviceProcessEvents
| where Timestamp >= ago(timeframe)
| where ActionType == "ProcessCreated"
    and (ProcessCommandLine contains "ollama" or InitiatingProcessCommandLine contains "ollama")
| project Timestamp, DeviceId, DeviceName, AccountName, ProcessName = FileName, ProcessCommandLine,
    RemoteIP = tostring(null), RemotePort = toint(null), RemoteUrl = tostring(null),
    UserAgent = tostring(null), ActivityType = "OllamaInCommandLine"
);
suspicious_events
| summarize StartTime = min(Timestamp), EndTime = max(Timestamp),
    ActivityTypes = make_set(ActivityType), RemoteIPs = make_set(RemoteIP),
    RemoteUrls = make_set(RemoteUrl), UserAgents = make_set(UserAgent)
    by DeviceId, DeviceName, AccountName, ProcessName, ProcessCommandLine
| extend ReportId = strcat(DeviceId, "-", tostring(hash_sha256(strcat(DeviceName, ProcessName, ProcessCommandLine))))
| extend AlertTitle = "Suspicious AI activity related to PromptLock Ransomware Activity"
| extend AlertDescription = strcat("Potential PromptLock activity detected on host ", DeviceName,
    " by user ", AccountName, ". Observed activities: ", tostring(ActivityTypes),
    ". Process: ", ProcessName, " with command line: ", ProcessCommandLine)
| project DeviceId, Timestamp = StartTime, ReportId, AccountName, ProcessName, ProcessCommandLine,
    EndTime, ActivityTypes, RemoteIPs, RemoteUrls, UserAgents

Detection engineering within Defender is arguably simpler than within Sentinel as it can be done directly from the Advanced Hunting screen. Assuming you've written, run and tested some KQL, simply click the "Create detection rule" button and select "Create custom detection" from the drop-down menu. Note here that you need to include specific columns to create a detection rule.

Enter the usual name, description, frequency and severity. From this screen you can also link the rule to recent threat intel briefs and provide recommended remediation actions.

In the following section we can adjust the alert title with dynamic naming and add custom details just like we could within Sentinel. Helpfully, it also pre-maps entities for us saving us time and effort, as well as removing the potential for human error.

The next screen, 'Automated Actions', is where some additional value is provided over Sentinel. From here we can isolate devices, run scans, collect investigation packages and restrict app executions automatically. We can also block and quarantine files, disable accounts, reset passwords and mark users as compromised without the need for logic apps. This massively reduces the time and effort for the implementing engineer, as well as provides a minor cost reduction attributed to the logic app runtime.

From the next screen we can scope the alert rule to specific device groups. Have a VIP group you want to treat with additional sensitivity? Or don't want to disable critical service accounts when an alert is generated? Simply assign the rule to run on specific device groups and it will exclude devices not in these groups when generating alerts.

The ability to interact directly with MDE and Entra is an innately powerful feature of custom detection rules within Defender. It increases the efficiency of not only the rule but also your analysts time and effort. It reduces the chance of errors during logic app development or entity mapping (which you would need to do confidently for aforementioned logic apps to even work!). The cost-savings are an even bigger bonus, allowing for visibility and detections within tables that were previously thought too costly to ingest or too difficult to modify with Data Collection Rules (DCR).

Overall, the benefits stated above are fundamental to optimising your security operations and streamlining your detection engineering processes. It provides visibility and gives time back to busy analysts or engineers who likely have a million different tasks and alerts to review, while simultaneously saving money for organisations with limited cybersecurity budgets.

References