image_name was left unmapped because HarfangLab prefixes it with the
matched threat name — "[PUADlManager:Win32/OfferCore] C:\Windows\
explorer.exe" — and the clean path was available from the event data.
That reasoning only held for event-log alerts. On the yara, binary and
ioc subtypes there is neither a `process` object nor an `eventlog`
block, so those alerts reached the incident with no process at all.
Both halves are now pulled out, each guarded on the bracket actually
being there: $substringBefore and $substringAfter return the whole
string when the pattern is absent, so without the guard an unprefixed
path would land verbatim in malware.name.
The three entries lead the process block so the more specific sources
below — the matched process object, then the event log's own fields —
still overwrite them when present. malware.name consequently surfaces on
every subtype instead of only where Defender is the source.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replayed a real get_alerts and a real get_threats response through the
bundled mappers to see what came out.
get_alerts: a sigma alert matching a Windows event log carries the whole
record under `eventlog`, and none of it was mapped. On a Defender 1116
detection that left the malware, the file, the acting user and the
detecting product invisible — the incident indexed a hostname and
nothing else. The event data uses the provider's own field names, spaces
included, so the new entries quote them with JSONata backticks, and
Defender's "file:_" path prefix is stripped. Also added the agent IP
(placed before details_connection.SourceIp so a network alert's own
source still wins), the DNS domain, device type, agent version and
groups, the tenant, the alert subtype and threat type, the string
severity and the event time.
get_threats: `level` had no entry at all, so a threat's severity never
reached the OCSF document even though field_mappings derived the
incident's 1-5 from it. Added it, the event time, and the top agent's
reachability — whether the endpoint is online decides what response is
possible, and it was excluded without a reason.
Both trailers now record why each remaining field is left out, and the
event log's own SYSTEM writer and FQDN spelling are called out: indexing
them would create a junk user entity and a second spelling of one host.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>