Threat Hunting

What Is a Hypothesis-Driven Hunt?

HuntRule Team · · 9 min read

A single wire snare set across one narrow game trail in dark undergrowth, fog behind it
On this page

Remote WMI process creation lands on the target as a child of C:\Windows\System32\wbem\WmiPrvSE.exe. That is one sentence of fact, and it is the entire reason the hunt below can exist. Without a fact like it you have a topic. With it you have a claim you can prove wrong before lunch.

A topic is not a hypothesis

"Hunt for lateral movement" is a topic. It names no data source, no field, no host population and no time window. It has no way to fail. You can spend three days inside it and finish with a paragraph saying nothing was found, which is indistinguishable from having done nothing at all.

A hypothesis is a statement about attacker behaviour in your environment that your telemetry can contradict. The test is whether you can write down, in advance, the exact rows that would make you wrong. If you cannot, you have a topic wearing a hypothesis costume.

Topic:       Hunt for lateral movement.

Hypothesis:  An operator using WMI for remote execution would leave
             WmiPrvSE.exe spawning command shells and script hosts on
             servers, under a non-SYSTEM logon session, in windows
             where no change record covers that host.

The second version names a parent process, a class of children, a host population, a session attribute and a scoping condition. Every one of those is a field in a log. Remove any of them and the query gets shorter while the result gets noisier.

The data source, and the exact fields

The primary source is process creation telemetry: Sysmon Event ID 1, or Security Event ID 4688 if that is all you have. 4688 only carries a command line when the "Include command line in process creation events" policy is enabled, and its parent field is called Creator Process Name (ParentProcessName in the XML), not ParentImage. Know which schema your index actually holds before you write the query.

Sysmon Event ID 1, fields this hunt reads:
  ParentImage        expect a path ending in \wbem\WmiPrvSE.exe
  ParentCommandLine  the provider host usually runs as -secured -Embedding
  Image              the child, which is the thing you care about
  CommandLine        needs Sysmon config that does not strip it
  User               the invoking account, arriving over the network
  LogonId            0x3e7 is the SYSTEM logon session
  IntegrityLevel     remote WMI execution as an admin lands at High
  Computer, UtcTime  host and pivot point

Two supporting sources close the loop. Security Event ID 4624 with LogonType 3 on the same host gives you IpAddress and TargetLogonId, which is how you turn "something ran here" into "it was pushed from there". On the domain controller, Event ID 4769 records the Kerberos service ticket the caller requested, with ServiceName naming the target host account.

The WMI operational log is weaker than its reputation. Microsoft-Windows-WMI-Activity/Operational Event ID 5857 records a provider starting, with ProviderName and HostProcess. Event ID 5858 carries ClientMachine, User and ResultCode, which is exactly what you want, except 5858 is only written on failure. A successful remote WMI execution normally leaves no 5858. Do not build the hunt on it.

The query

Against a normalised process table, the whole hypothesis is about six lines.

SELECT host, utc_time, user, logon_id, image, command_line, parent_command_line
FROM process_creation
WHERE parent_image LIKE '%\wbem\WmiPrvSE.exe'
  AND logon_id NOT IN ('0x3e7')
  AND user NOT LIKE '%AUTHORI%'
  AND user NOT LIKE '%AUTORI%'
  AND utc_time > now() - interval '14 days'
ORDER BY host, utc_time

The AUTHORI and AUTORI substrings are not a typo. They are how SigmaHQ excludes NT AUTHORITY across localised installs, and they belong here for the same reason.

Two transports reach the same artifact. DCOM lands on TCP 135 plus a dynamic RPC port, WinRM lands on 5985 or 5986. In both cases Win32_Process::Create is serviced by the provider host, so the child sits under WmiPrvSE.exe either way. We reconstructed this in a lab over DCOM only:

$opt = New-CimSessionOption -Protocol Dcom
$s = New-CimSession -ComputerName LAB-SRV-01 -SessionOption $opt
Invoke-CimMethod -CimSession $s -ClassName Win32_Process -MethodName Create `
  -Arguments @{ CommandLine = 'cmd.exe /c ver' }

We did not test the WinRM transport, so treat the parentage claim for 5985 traffic as expected rather than confirmed.

Scoping out the known-good

Run that query in a real estate and you will get thousands of rows on day one. Almost all of it is management software. Configuration Manager, App-V, backup agents, monitoring agents and credentialed vulnerability scans all drive remote WMI as a matter of routine, and SigmaHQ lists Configuration Manager, App-V and WinRM among the expected false positives on its WmiPrvSE rules.

Do not filter by process name. Filter by tuple frequency, because the account and source host are what make a row boring, not the binary.

SELECT image, user, count(*) AS n, count(DISTINCT host) AS hosts
FROM process_creation
WHERE parent_image LIKE '%\wbem\WmiPrvSE.exe'
  AND utc_time > now() - interval '90 days'
GROUP BY image, user
ORDER BY n DESC

Read that list from the bottom. A service account touching 4,000 hosts every night is infrastructure. A domain admin account touching one server once, at 03:12, is the hunt. The exclusion list you build here is worth more than the hunt itself, and it is the part you cannot download from anyone.

What a negative result actually means

This is where most hunts quietly fail. The query returns nothing and the hunter writes "no evidence of WMI lateral movement". Three very different situations produce that same empty table, and only one of them is a finding.

A floodlight sweeping open ground at night with one hard wedge of complete shadow cast behind an upright post
  1. The sensor was never there. Count Event ID 1 volume per host over the window and compare it to your asset inventory. Servers with zero process events did not stay quiet, they were never instrumented.

  2. The events existed and never reached you. Forwarder outage, index retention shorter than your window, or a parser that maps ParentImage to process.parent.executable and silently drops your LIKE clause. Query one host you know ran WMI yesterday and confirm you can see it.

  3. The behaviour did not happen.

Only the third is a result. The first two are data-source gaps, and they are more valuable than the negative, because they tell you a whole class of hunts is currently untestable. A hunter who reports a clean negative on hosts with no Sysmon has reported the coverage of their agent, not the state of their network.

What you write down either way

Write the same record regardless of outcome. Hypothesis as stated. Data sources and index names. Time window and host scope. Query verbatim. Row count before and after exclusions. Every exclusion with the reason it was applied. Outcome as one of: true positive, coverage gap, or tested negative. Then the next hypothesis this one suggested.

That record is what makes the hunt repeatable in six months by someone who is not you. It is also the only defence against re-running the same hunt three times because nobody remembered it was already answered.

Where hypotheses come from

Four sources, in rough order of how much they are worth.

  • Environment knowledge. You know WMI is only used by two service accounts, so a third one is anomalous by construction. These are the best hypotheses because they encode something no external report can, and they produce specific queries with small result sets.

  • Incident lessons. Something got through once. The hypothesis is that the same path is still open, and you already know the artifacts it leaves.

  • ATT&CK coverage gaps. Map what you detect, find the empty cells, hypothesise into them. Systematic, but it produces generic hypotheses that fit any network and therefore fit yours only loosely.

  • Threat intelligence. A report describes a technique. Useful, but the report was written about someone else's estate, and the hypothesis needs translating into your account names and host groups before it means anything.

Intel-driven hunts tend to be popular because they arrive pre-written. Environment-driven hunts win because attackers have to operate in your environment, not in the report's.

The durable output

A hunt that ends in a Slack message ends. Force it into one of three artifacts.

A detection rule. This hypothesis already has one upstream: SigmaHQ ships WmiPrvSE Spawned A Process with id d21374ff-f574-44a7-9998-4a8c8bf33d7d, filtering on LogonId 0x3e7 and the localised NT AUTHORITY strings. Your contribution is the tuned local variant plus the exclusion list you earned during scoping, which is the part no upstream rule can carry. If Sigma as a format is new to you, start at what are Sigma rules, then browse the existing Windows coverage at /rules?domain=windows.

logsource:
    category: process_creation
    product: windows
detection:
    selection:
        ParentImage|endswith: '\WmiPrvSE.exe'
        Image|endswith:
            - '\cmd.exe'
            - '\powershell.exe'
            - '\pwsh.exe'
            - '\cscript.exe'
            - '\wscript.exe'
            - '\mshta.exe'
    filter_system:
        LogonId: '0x3e7'
    filter_localised_system:
        User|contains:
            - 'AUTHORI'
            - 'AUTORI'
    condition: selection and not 1 of filter_*

What it catches: interactive shells and script hosts pushed over WMI by a named account. What it misses: an operator who calls a binary that is not on the list, or who uses a script-based WMI event subscription for execution instead of Win32_Process, which runs under scrcons.exe and produces no WmiPrvSE.exe child at all. Known false positives: Configuration Manager, App-V, credentialed scanners, and any WinRM automation your ops team owns.

A data-source gap ticket. "Sysmon absent on 41 servers in the finance OU" is a deliverable with an owner and a due date.

A documented negative. Dated, scoped, with the query attached, so the next person can re-run it in one command instead of one week.

ATT&CK techniques

ID

Title

Tactic

T1047

Windows Management Instrumentation

Execution

T1021.003

Remote Services: Distributed Component Object Model

Lateral Movement

T1021.006

Remote Services: Windows Remote Management

Lateral Movement

T1059.001

Command and Scripting Interpreter: PowerShell

Execution

T1059.003

Command and Scripting Interpreter: Windows Command Shell

Execution

Summary

A hypothesis names a parent process, a field, a host population and a window, and it can be shown false. A topic cannot. Walking one hypothesis end to end costs an afternoon and produces a rule, a gap ticket or a dated negative, all three of which outlive the hunt. The negative is only worth writing once you have proven your telemetry could have seen the behaviour, because an empty result from an uninstrumented host is a statement about your agent rollout. Start from what you know about your own environment, since that is the one thing an attacker has to work inside and a threat report cannot describe. Rules covering this technique and its neighbours are at /rules?q=wmi.

Collect before running this hunt:
  Sysmon Event ID 1        process creation, ParentImage retained
  Security Event ID 4688   fallback, needs command line audit policy
  Security Event ID 4624   LogonType 3, for IpAddress and TargetLogonId
  Security Event ID 4769   on DCs, ServiceName of the target host
  WMI-Activity 5857        provider start, ProviderName and HostProcess
  WMI-Activity 5858        failures only, carries ClientMachine

Related articles