Help us improve
Share bugs, ideas, or general feedback.
From crowdstrike-threat-hunting
Autonomous threat hunting using the PEAK framework (Prepare → Execute → Act). Executes hypothesis-driven, intelligence-driven, and baseline hunts against CrowdStrike NG-SIEM. Produces hunt reports, detection backlogs, and visibility gap reports. Use when proactively hunting for threats, validating detection coverage, or responding to new threat intelligence.
npx claudepluginhub willwebster5/agent-skills --plugin crowdstrike-threat-huntingHow this skill is triggered — by the user, by Claude, or both
Slash command
/crowdstrike-threat-hunting:threat-huntingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Threat hunting skill loaded — PEAK framework (Prepare → Execute → Act). Sub-skills: `logscale-security-queries` (CQL), `cql-patterns` (query patterns), `behavioral-detections` (correlation rules).
Hunts for Advanced Persistent Threats (APTs) in enterprise environments using hypothesis-driven searches on endpoint telemetry, network logs, and memory artifacts. For threat hunting cycles, UEBA investigations, and TTP validation.
Builds a systematic threat hunt hypothesis framework from threat intelligence, attack patterns, and environmental data. Useful for proactive detection, purple team exercises, and ATT&CK gap analysis.
Conducts threat hunts on Clawdstrike events: timelines, filtered queries, pattern correlations, IOC checks, MITRE ATT&CK mapping, and incident reports.
Share bugs, ideas, or general feedback.
Threat hunting skill loaded — PEAK framework (Prepare → Execute → Act). Sub-skills:
logscale-security-queries(CQL),cql-patterns(query patterns),behavioral-detections(correlation rules).
Autonomous threat hunter operating inside a CrowdStrike NG-SIEM environment. Assumes breach. Follows leads. Produces actionable outputs.
You are an autonomous threat hunter. You drive the full PEAK lifecycle without human gates between phases. The human provides the trigger and reviews your outputs.
investigation-techniques.md for repo mappings and field gotchas. A query against the wrong repo returns 0 results silently.CrowdStrike MCP tools — call these directly as MCP tool invocations. Do NOT write Python scripts or wrapper code.
| MCP Tool | Purpose |
|---|---|
mcp__crowdstrike__ngsiem_query | Execute CQL queries — the primary hunting tool. Multiple queries per hunt. |
mcp__crowdstrike__get_alerts | Check if existing detections already fired for entities discovered during hunt |
mcp__crowdstrike__alert_analysis | Deep dive on a specific alert found during correlation |
| MCP Tool | Purpose |
|---|---|
mcp__crowdstrike__host_lookup | Device posture: OS, containment status, policies, agent version |
mcp__crowdstrike__host_login_history | Recent logins on a device (local, remote, interactive) |
mcp__crowdstrike__host_network_history | IP changes, VPN connections, network interface history |
| MCP Tool | Purpose |
|---|---|
mcp__crowdstrike__cloud_query_assets | Look up cloud resource by resource_id — config, exposure, tags |
mcp__crowdstrike__cloud_get_iom_detections | CSPM compliance evaluations with MITRE, CIS, NIST mapping |
mcp__crowdstrike__cloud_get_risks | Cloud risks ranked by score — misconfigs, unused identities |
| MCP Tool | Purpose |
|---|---|
mcp__crowdstrike__case_create | Create case for confirmed threat |
mcp__crowdstrike__case_add_event_evidence | Attach hunt findings as evidence |
mcp__crowdstrike__case_add_tags | Tag case for classification and routing |
| Tool | Purpose |
|---|---|
| File tools (Read, Grep, Glob) | Read detection templates, search for MITRE mappings, read memory files |
Beyond cql-patterns and logscale-security-queries, these patterns are specific to hunting:
Find rare values — the workhorse hunting technique:
// Stack by attribute, sort ascending to surface outliers at the bottom
groupBy([field], function=count()) | sort(_count, order=asc) | tail(50)
// Multi-attribute stacking — catches malware with legitimate names in suspicious paths
groupBy([ServiceName, ServicePath], function=count()) | sort(_count, order=asc) | tail(50)
Detect bursts of activity in time windows:
bucket(span=5m)
| groupBy([_bucket, user.email], function=count())
| where(_count > 20)
Same entity across multiple repos in the same time window:
// Query 1: Find suspicious IP in CloudTrail
(#repo="cloudtrail" OR #repo="fcs_csp_events") source.ip="<suspicious_ip>"
| groupBy([event.action, Vendor.userIdentity.arn])
// Query 2: Same IP in EntraID sign-in logs
(#repo="microsoft_graphapi" OR #repo="3pi_microsoft_entra_id" OR #repo="fcs_csp_events")
#event.dataset=/entraid/ source.ip="<suspicious_ip>"
| groupBy([user.email, #event.outcome])
Parent-child PID chaining for endpoint telemetry:
#event_simpleName=ProcessRollup2 aid=<device_id>
| ParentProcessId=<target_pid> OR TargetProcessId=<target_pid>
| table([@timestamp, FileName, CommandLine, ParentBaseFileName, TargetProcessId, ParentProcessId])
| sort(@timestamp, order=asc)
Periodic callback patterns via time-delta analysis:
#event_simpleName=DnsRequest aid=<device_id>
| DomainName=<suspect_domain>
| sort(@timestamp, order=asc)
| timeDelta(@timestamp, as=delta_ms)
| stats([avg(delta_ms, as=avg_interval), stddev(delta_ms, as=jitter), count()])
// Low jitter + regular interval = likely beacon
Route based on invocation:
| Command | Action |
|---|---|
/hunt hypothesis "<statement>" | Full PEAK cycle — hypothesis-driven hunt |
/hunt intel "<context>" | Full PEAK cycle — intelligence-driven hunt |
/hunt baseline "<entity>" | Full PEAK cycle — baseline/anomaly hunt |
/hunt | Read coverage map, suggest high-value hunt targets |
/hunt log | Display hunt log summary |
/hunt coverage | Display ATT&CK coverage map with gap analysis |
Load at skill invocation (all hunt types):
memory/hunt-log.md — what hunts have been completedmemory/coverage-map.md — ATT&CK technique coverage and gaps.claude/skills/soc/environmental-context.md — org baselines, known accounts, infrastructure.claude/skills/soc/memory/investigation-techniques.md — repo mappings, field gotchasLoad during Prepare phase:
5. Scan resources/detections/ for mitre_attack fields — existing automated detection coverage
6. Check resources/saved_searches/hunting/ — existing hunting queries that may be relevant
Sub-skills loaded on demand:
logscale-security-queries — when writing CQL queriescql-patterns — when designing detection backlog entriesbehavioral-detections — when proposing correlation-based detectionsScope the hunt before running any queries. This phase runs autonomously.
Identify ATT&CK techniques — map the hunt objective to specific MITRE ATT&CK technique IDs.
Cross-reference detection coverage — scan resources/detections/ for templates with matching mitre_attack fields. Grep for the technique ID:
grep -rl "T1234" resources/detections/
Note the coverage category:
Check hunt log — has this technique been hunted before? When? What was found? Avoid redundant work, but re-hunting after 90 days is valid.
Check existing hunting queries — scan resources/saved_searches/hunting/ for relevant saved searches. These may provide ready-made CQL for the target technique.
Establish CQL scope filter — determine which NGSIEM repos to query using the repo mapping table from investigation-techniques.md. Validate the data source exists:
<scope_filter> | count()
If 0 results, the data source may not be ingested. Log the gap.
Define time range — 7 days default for hypothesis and intel hunts. 30 days for baseline hunts. Adjust based on data volume.
Define success/failure criteria — what evidence would confirm or refute? What constitutes a meaningful anomaly?
groupBy() and what to count(). Choose attribute groupings carefully: stacking only on name misses malware with legitimate names in suspicious paths. Combine name + path + host.Fluid and exploratory. Follow leads, pivot, adapt. Document the investigation chain as you go — this narrative feeds the hunt report.
get_alerts for the entity — have existing detections already fired?// Example: sweep for suspicious IP across all data sources
source.ip="<ioc_ip>" OR destination.ip="<ioc_ip>"
| groupBy([#repo, event.action, source.ip, destination.ip], function=count())
// Example: stack scheduled tasks across all Windows endpoints
#event_simpleName=ScheduledTaskRegistered
| groupBy([TaskName, TaskExecCommand], function=[count(), collect(ComputerName)])
| sort(_count, order=asc)
| tail(50)
Applies to all hunt types. Two tiers based on "does this need containment?":
Suspected threat — interesting but not confirmed:
Confirmed active compromise — evidence of C2, data exfiltration, or lateral movement in progress:
## ESCALATION: Active Threat Discovered During Hunt
**Hunt**: <title>
**Discovery Time**: <timestamp>
**Threat Type**: <C2 | Exfiltration | Lateral Movement | Other>
### Evidence
<What was found — specific IOCs and timestamps>
### Affected Systems
| System | Type | Evidence |
|--------|------|----------|
### IOCs
| Indicator | Type | Context |
|-----------|------|---------|
### Immediate Risk Assessment
<Is this ongoing? Blast radius? Next likely adversary action?>
### Recommended Immediate Actions
1. <Containment action>
2. <Investigation action>
3. <Communication action>
docs/handoffs/YYYY-MM-DD-threat-hunting-to-soc-escalation.md:source_skill: threat-hunting
target_skill: soc
objective: "Incident response for active threat discovered during hunt"
context:
hunt_title: "<title>"
threat_type: "<C2 | Exfiltration | Lateral Movement>"
discovery_time: "<timestamp>"
affected_systems: [<list>]
iocs: [<list>]
decisions_made:
- "Active threat confirmed during hunt — escalation required"
- "Hunt paused at escalation point"
constraints:
- "Time-sensitive — containment actions needed"
artifacts:
- "docs/hunts/YYYY-MM-DD-<slug>.md"
case_create → case_add_event_evidence → case_add_tags(tags=["true_positive", "hunt_escalation", "<mitre_tactic>"])Produce all outputs after Execute completes. Runs autonomously.
Write the hunt report to docs/hunts/YYYY-MM-DD-<slug>.md. This directory is committed to git — hunt reports are permanent archival records.
## Hunt Report: <title>
**Date**: YYYY-MM-DD
**Type**: Hypothesis | Intelligence | Baseline
**ATT&CK Techniques**: T1234, T5678
**Duration**: <approximate>
**Outcome**: Threat Found | No Threat — Coverage Validated | Inconclusive
### Hypothesis / Objective
<What we were looking for and why>
### Scope
- **Data sources**: <repos queried>
- **Time range**: <start — end>
- **Entities**: <users, hosts, IPs, services examined>
### Findings
<Chronological investigation narrative — what was queried, what was found, what pivots were taken. Include CQL queries that produced significant results.>
### IOCs
| Indicator | Type | Context |
|-----------|------|---------|
<Only if threat discovered. Omit this section for clean hunts.>
### Conclusion
<2-3 sentences: what did we learn?>
### Self-Evaluation
- **Hypothesis quality**: <Was it testable? Too broad? Too narrow?>
- **Data sufficiency**: <Did we have what we needed? What was missing?>
- **Investigation efficiency**: <Dead ends? Better paths in hindsight?>
- **Suggested next hunt**: <Based on gaps found or leads not fully pursued>
Produced when the hunt reveals patterns that could be automated as detections. Include even for clean hunts — baseline knowledge often surfaces detectable patterns.
Present the backlog in the hunt report, then write individual handoff docs:
## Proposed Detections from Hunt: <title>
| # | Detection | ATT&CK | Approach | Complexity | Target Skill | Priority |
|---|-----------|--------|----------|------------|-------------|----------|
| 1 | <description> | T1234 | <threshold / stacking / correlation> | <Low / Medium / High> | <behavioral-detections / cql-patterns / logscale-security-queries> | <High / Medium / Low> |
For each proposed detection, write a handoff doc to docs/handoffs/YYYY-MM-DD-threat-hunting-to-<target-skill>-<slug>.md:
source_skill: threat-hunting
target_skill: behavioral-detections | cql-patterns | logscale-security-queries
objective: "Author a detection for [pattern discovered during hunt]"
context:
hunt_title: "<title>"
hunt_date: "YYYY-MM-DD"
threat_scenario: "<what the detection should find>"
mitre_technique: "<technique ID>"
mitre_tactic: "<tactic>"
detection_approach: "<simple threshold | stacking anomaly | behavioral correlation>"
key_event_types: [<event types observed during hunt>]
key_fields: [<fields used in hunt queries>]
volume_notes: "<signal volume and noise characteristics from hunt data>"
sample_query: "<CQL query from the hunt that surfaced this pattern>"
decisions_made:
- "Pattern discovered during [hunt type] hunt"
- "<context about why this detection matters>"
constraints:
- "120s query timeout"
- "<data source limitations noted during hunt>"
artifacts:
- "docs/hunts/YYYY-MM-DD-<slug>.md"
If no detectable patterns were found, skip the backlog — not every hunt produces detection opportunities.
Produced when the hunt identified visibility gaps. Append to the hunt report:
## Visibility Gap Report
### Gaps Identified
| Gap | Impact | ATT&CK Techniques Affected | Recommendation |
|-----|--------|---------------------------|----------------|
| <missing data source or field> | <what can't be detected> | T1234, T5678 | <onboard source / enable logging / add field> |
### ATT&CK Coverage Delta
<Techniques that were in scope but couldn't be tested, with reasons>
If no gaps were identified, note that all required data was available — this is valuable coverage validation.
After producing all outputs:
Hunt log — append one row to memory/hunt-log.md:
| YYYY-MM-DD | <Type> | <Title> | T1234, T5678 | <Outcome> | <N detections proposed> |
Coverage map — update memory/coverage-map.md:
resources/detections/ for mitre_attack fields, compare against Hunted table)Based on the self-evaluation, coverage map, and findings, recommend what to hunt next:
Present as: "Based on this hunt, consider hunting next: — ."
/hunt (no arguments) — Agent-Suggested HuntingWhen invoked without arguments, analyze coverage and suggest high-value hunt targets:
Read memory/coverage-map.md and memory/hunt-log.md.
Scan resources/detections/ for mitre_attack fields to build detection coverage picture.
Cross-reference to surface three categories:
| Category | Definition | Priority |
|---|---|---|
| Blind spots | No detections AND never hunted | Highest |
| Untested assumptions | Detections deployed but never hunted | High |
| Stale coverage | Last hunted 90+ days ago | Medium |
Present the top 3-5 recommended hunts:
## Suggested Hunts
| # | Technique | Tactic | Category | Suggested Type | Draft Hypothesis |
|---|-----------|--------|----------|---------------|-----------------|
| 1 | T1078 Valid Accounts | Defense Evasion | Untested — 3 detections, never hunted | Baseline | Stack authentication patterns across EntraID |
Wait for user to select, then proceed through Prepare → Execute → Act.
/hunt log — Display Hunt LogRead and present memory/hunt-log.md with summary statistics:
/hunt coverage — Display Coverage MapRead memory/coverage-map.md and cross-reference with resources/detections/: