<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
<!-- NERF is a trademark of defconxt. -->

# Threat Hunting Reference

Deep reference for hypothesis-driven hunting, endpoint security, network monitoring,
vulnerability management, and identity security.
Parent skill: [../SKILL.md](../SKILL.md)

---

## Hypothesis-Driven Hunting Framework

```
Hypothesis: Attacker used scheduled tasks for persistence after initial access
Data source: Windows EID 4698/4702, Sysmon EID 1 (schtasks.exe)
Baseline: Scheduled tasks created in last 30 days vs. approved list
Query (KQL):
  SecurityEvent
  | where EventID in (4698, 4702)
  | where AccountName !in ("SYSTEM", "LOCAL SERVICE")
  | summarize count() by SubjectAccountName, TaskName, bin(TimeGenerated, 1h)
Hit condition: New tasks from non-admin accounts or tasks running from %TEMP%/%AppData%
```

### Stack Counting Pattern (Splunk)

```spl
index=windows EventCode=4688
| stats count by ParentProcessName, Process
| sort -count
| where count < 5  # rare parent-child relationships
```

### Frequency Analysis — Baseline Rare Processes

```bash
# Linux: find processes running infrequently
aureport -x --summary | sort -rn | tail -20
```

### Hunt Hypotheses Worth Pursuing

| Technique | Hypothesis | Data Source | Hit Condition |
|---|---|---|---|
| T1053 | Scheduled task persistence | EID 4698/4702 | New tasks with UNC paths or %TEMP% execution |
| T1078 | Valid accounts abuse | EID 4624 | Successful logon from user not seen in 30 days |
| T1070 | Indicator removal | EID 1102, auditd | Event log cleared, auditd disabled |
| T1190 | Exploit public-facing app | Web server logs | Web server spawning sh/cmd as child process |

### Anti-Pattern

Hunting without a data source inventory first — know which log sources you actually have before writing queries. A missing Sysmon deployment makes process lineage hunts impossible.

---

## Endpoint Security

### EDR Telemetry Gap Analysis

Map detection coverage against MITRE ATT&CK using the Navigator: `https://mitre-attack.github.io/attack-navigator/`

Common gaps:
- T1055 process injection (needs Sysmon EID 8/10)
- T1070.004 file deletion
- T1218 LOLBin execution

### Sysmon Baseline (SwiftOnSecurity + Extensions)

```xml
<!-- Key rule examples -->
<RuleGroup name="ProcessCreate">
  <ProcessCreate onmatch="include">
    <Rule name="Execution from AppData" groupRelation="and">
      <Image condition="contains">\AppData\</Image>
    </Rule>
    <Rule name="LOLBAS" groupRelation="or">
      <Image condition="endswith">\regsvr32.exe</Image>
      <Image condition="endswith">\mshta.exe</Image>
      <Image condition="endswith">\wscript.exe</Image>
    </Rule>
  </ProcessCreate>
</RuleGroup>
<RuleGroup name="ProcessAccess">
  <ProcessAccess onmatch="include">
    <TargetImage condition="endswith">\lsass.exe</TargetImage>
  </ProcessAccess>
</RuleGroup>
```

Verify Sysmon config coverage: `sysmon -c` shows active config; `sysmon-modular` provides ATT&CK-mapped modules.

### CrowdSec IPS Deployment

```bash
# Install and enroll
apt install crowdsec && cscli hub update
# Install collections (scenarios + parsers)
cscli collections install crowdsecurity/linux
cscli collections install crowdsecurity/sshd
cscli collections install crowdsecurity/nginx
# Add bouncer (actual blocking)
apt install crowdsec-firewall-bouncer-nftables
# Verify decisions
cscli decisions list
# Community blocklist (requires cscli lapi register)
cscli capi register
```

CrowdSec acquisition config (`/etc/crowdsec/acquis.yaml`):
```yaml
filenames:
  - /var/log/auth.log
  - /var/log/nginx/access.log
labels:
  type: syslog
---
filenames:
  - /var/log/nginx/access.log
labels:
  type: nginx
```

**Anti-pattern:** Deploying CrowdSec without bouncers — it detects but doesn't block. Always pair with firewall bouncer.

---

## Network Security Monitoring

### Suricata Rule Syntax and Deployment

```yaml
# /etc/suricata/suricata.yaml key settings
af-packet:
  - interface: eth0
    threads: 4
    cluster-id: 99
    cluster-type: cluster_flow
default-log-dir: /var/log/suricata/
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: eve.json
      types:
        - alert
        - http
        - dns
        - tls
```

Suricata rule example (lateral movement detection):
```
alert tcp $HOME_NET any -> $HOME_NET 445 (msg:"ET POLICY SMB2 NT_TRANSACT_RENAME attempt"; flow:established,to_server; content:"|FF|SMB"; offset:4; depth:4; content:"|A0 00|"; distance:56; within:2; sid:2010252; rev:3;)
```

### Zeek Log Analysis

```bash
# Detect port scans (many unique destination ports from single source)
cat /var/log/zeek/conn.log | zeek-cut id.orig_h id.resp_p proto | sort | uniq | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# Find long DNS TXT records (potential C2 tunneling)
cat /var/log/zeek/dns.log | zeek-cut query answers | awk 'length($2) > 100'
# TLS without SNI (C2 traffic pattern)
cat /var/log/zeek/ssl.log | zeek-cut id.orig_h id.resp_h server_name | awk '$3 == "-"'
# Detect beaconing (regular intervals)
cat /var/log/zeek/conn.log | zeek-cut ts id.orig_h id.resp_h | awk '{print $2,$3,$4}' | sort | uniq -c
```

### DNS Security

- **RPZ (Response Policy Zones):** block known malicious domains at resolver
- **Passive DNS:** `zeek-cut query` → correlate new/rare domains against registration date
- **DGA detection:** entropy analysis on domain names:
  ```bash
  cat dns.log | zeek-cut query | python3 -c "import sys,math; [print(d, -sum(d.count(c)/len(d)*math.log2(d.count(c)/len(d)) for c in set(d))) for d in sys.stdin]"
  ```

### Anti-Pattern

IDS rules without tuning — a Suricata ruleset with default community rules generates thousands of alerts/day. Start with ET-OPEN + local rules for your stack, suppress known benign.

---

## Vulnerability Management

### Prioritization Workflow

1. **CISA KEV** (Known Exploited Vulnerabilities) — patch within KEV mandated timeframes regardless of CVSS
2. **EPSS > 0.1 AND CVSS ≥ 7.0** — high exploitability risk
3. **CVSS ≥ 9.0 internet-exposed** — critical regardless of EPSS
4. Everything else — risk-accept or schedule maintenance window

### CVSS Vector Parsing Example

```
CVE-2024-1234: CVSS 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
AV:N = network-reachable, AC:L = no special conditions, PR:N = no auth needed
→ Remote unauthenticated RCE: patch immediately
```

### Scan and Verify

```bash
# OpenVAS/Greenbone
gvm-cli --gmp-username admin --gmp-password pass tls --hostname localhost create-task --name "CIS Audit" --target-id <id>
# Nuclei targeted scan
nuclei -u https://target -t cves/ -severity critical,high -o findings.txt
# Verify patch applied
dpkg -l <package> | grep ^ii  # Debian
rpm -q <package>              # RHEL
```

### Asset Criticality Weighting

internet-facing > data store > authentication > internal

### SLA Definitions

| Severity | Remediation Window |
|---|---|
| Critical | 24 hours |
| High | 7 days |
| Medium | 30 days |
| Low | 90 days |

### Anti-Pattern

CVSS-only prioritization — a CVSS 9.8 vuln in an isolated dev environment is lower priority than a CVSS 7.0 in internet-facing auth service. Always apply asset context.

---

## Identity Security

### Zero Trust Access Model

- Never trust network location — authenticate every connection regardless of source
- Enforce MFA: FIDO2/passkeys > TOTP > push notifications > SMS (in order of phishing resistance)
- Conditional access: device compliance check + risk score before access grant

### Service Account Hygiene

- Disable interactive login: `usermod -s /sbin/nologin svcaccount`
- Rotate API keys/tokens: 90-day rotation policy minimum
- Audit unused accounts: `lastlog | grep "Never logged in"` → review and disable

### JIT Access

Request-approve-grant-expire cycle. Bastion host or PAM solutions (CyberArk, HashiCorp Vault) for privileged sessions.

### Anti-Pattern

MFA on web portal but not on VPN/SSH — attackers bypass the web portal and hit SSH directly. MFA everywhere or it's theater.

---
v1.1 | Validated: 2026-03-13
