Featured image of post Threat Hunting with MITRE ATT&CK

Threat Hunting with MITRE ATT&CK

A structured methodology for hypothesis-driven threat hunting using the MITRE ATT&CK framework — from selecting techniques to building hunt packages, writing SIEM queries, and documenting findings.

Overview

Threat hunting is the proactive search for adversary activity that has evaded automated detection. Unlike alert-driven investigation, hunting starts with a question — a hypothesis — and works backwards through the data to either confirm or rule it out.

MITRE ATT&CK provides the vocabulary. Every hypothesis maps to a technique. Every technique maps to specific data sources, artifacts, and detection logic. This methodology turns ATT&CK from a reference document into an operational hunting programme.


The Hunting Cycle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1. HYPOTHESISE
   Select a technique based on:
   - Recent threat intel (what TTPs are actors targeting your sector using?)
   - Gaps in current detection coverage
   - Anomalies spotted in routine monitoring
2. DEFINE SCOPE
   - What data sources cover this technique?
   - What timeframe?
   - Which asset groups are in scope?
3. COLLECT & QUERY
   - Write SIEM/EDR queries
   - Pull relevant logs
4. ANALYSE
   - Filter noise, cluster anomalies
   - Investigate interesting results manually
5. RESPOND OR DOCUMENT
   - If malicious found → open incident
   - If not found → document as baseline
6. IMPROVE DETECTION
   - Convert hunt logic into permanent detection rules
   - Fill the coverage gap that motivated the hunt

Hunt Package Structure

Each hunt is documented as a “hunt package” — a reusable, shareable unit of work.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
hunt_id: HUNT-2026-014
title: "Hunting for T1059.001 — PowerShell Abuse"
mitre_technique: T1059.001
mitre_tactic: Execution
hypothesis: >
  Threat actors in our sector are using encoded PowerShell commands to
  download and execute second-stage payloads. Our current detection
  only covers known-bad hashes, not the execution behaviour itself.
data_sources:
  - Windows Event Logs (Event ID 4104 — Script Block Logging)
  - Sysmon Event ID 1 (Process Creation)
  - EDR telemetry
timeframe: 30 days
asset_scope: All Windows endpoints
analyst: Mohammad Al Sayegh
status: Completed
outcome: 3 suspicious scripts found — 1 escalated to incident

Hunt 1: PowerShell Abuse (T1059.001)

Hypothesis

Attackers are using Base64-encoded PowerShell to bypass detection and download payloads.

Data Source

Windows Event ID 4104 (Script Block Logging must be enabled)

Query — Splunk

1
2
3
4
5
6
7
index=wineventlog EventCode=4104
| search ScriptBlockText="*-EncodedCommand*" OR ScriptBlockText="*[Convert]::FromBase64String*"
        OR ScriptBlockText="*IEX*" OR ScriptBlockText="*Invoke-Expression*"
| eval script_length=len(ScriptBlockText)
| where script_length > 500
| stats count by Computer, UserID, ScriptBlockText
| sort -count

Query — KQL (Microsoft Sentinel)

1
2
3
4
5
6
7
SecurityEvent
| where EventID == 4104
| where ScriptBlockText has_any ("-EncodedCommand", "FromBase64String", "IEX", "Invoke-Expression", "DownloadString")
| extend ScriptLength = strlen(ScriptBlockText)
| where ScriptLength > 500
| summarize Count = count() by Computer, Account, ScriptBlockText
| sort by Count desc

What to Look For

  • Long Base64 strings (>500 chars) being decoded at runtime
  • IEX combined with DownloadString or WebClient — classic download cradle
  • Scripts executing from unusual parent processes (outlook.exe, winword.exe, excel.exe)
  • Scripts with no file path (run in-memory from a macro or remote trigger)

Hunt 2: Living Off the Land Binaries — LOLBins (T1218)

Hypothesis

Attackers are abusing signed Windows binaries to proxy the execution of malicious code and bypass application whitelisting.

Data Source

Sysmon Event ID 1 (Process Creation), Windows Event ID 4688

Query — Splunk

1
2
3
4
5
6
7
8
index=sysmon EventCode=1
(Image="*certutil.exe*" OR Image="*regsvr32.exe*" OR Image="*mshta.exe*"
 OR Image="*wscript.exe*" OR Image="*cscript.exe*" OR Image="*rundll32.exe*"
 OR Image="*msiexec.exe*" OR Image="*installutil.exe*")
| search (CommandLine="*http*" OR CommandLine="*ftp*" OR CommandLine="*decode*"
          OR CommandLine="*urlcache*" OR CommandLine="*scrobj*")
| table _time, Computer, User, Image, CommandLine, ParentImage
| sort -_time

High-Value Patterns

Binary Suspicious Usage ATT&CK
certutil.exe -urlcache -split -f http://... — downloads file T1105
regsvr32.exe /s /n /u /i:http://... — COM scriptlet from URL T1218.010
mshta.exe Executing remote .hta file T1218.005
rundll32.exe Loading DLL from a network share T1218.011
wmic.exe Remote process execution via process call create T1047

Hunt 3: Persistence via Registry Run Keys (T1547.001)

Hypothesis

A threat actor has established persistence by adding a registry run key that executes a payload on every user login.

Data Source

Sysmon Event ID 13 (Registry Value Set), Windows Event ID 4657

Query — Splunk

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
index=sysmon EventCode=13
TargetObject IN (
    "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run*",
    "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce*",
    "*\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run*",
    "*HKCU\\Environment\\UserInitMprLogonScript*"
)
| where NOT (Image IN ("C:\\Windows\\System32\\msiexec.exe",
                        "C:\\Program Files\\*",
                        "C:\\Program Files (x86)\\*"))
| table _time, Computer, User, Image, TargetObject, Details
| sort -_time

What Makes It Suspicious

  • The registry writer is not an installer (msiexec, vendor software)
  • The value points to a temp directory, %AppData%, %Temp%, or a network path
  • The binary written to the key is not digitally signed
  • The key was written shortly after a phishing email was opened (correlate with email logs)

Hunt 4: Credential Dumping via LSASS (T1003.001)

Hypothesis

An attacker has obtained code execution and is attempting to dump LSASS memory to extract plaintext credentials or NTLM hashes.

Data Source

Sysmon Event ID 10 (Process Access), Windows Event ID 4656

Query — Splunk

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
index=sysmon EventCode=10
TargetImage="*lsass.exe"
NOT (SourceImage IN (
    "C:\\Windows\\System32\\werfault.exe",
    "C:\\Windows\\System32\\taskmgr.exe",
    "C:\\Program Files\\*",
    "C:\\Windows\\System32\\svchost.exe"
))
| eval suspicious_access=if(match(GrantedAccess,"0x1010|0x1410|0x1438|0x143a|0x1fffff"),1,0)
| where suspicious_access=1
| table _time, Computer, SourceImage, SourceUser, GrantedAccess
| sort -_time

Key Access Rights to Flag

Access Mask Meaning Risk
0x1010 Read + VM Read Common Mimikatz pattern
0x1410 Read + Query Info + VM Read Procdump pattern
0x1fffff Full access Highly suspicious

Hunt 5: Lateral Movement via Pass-the-Hash (T1550.002)

Hypothesis

An attacker with harvested NTLM hashes is authenticating to other systems without knowing the plaintext password.

Data Source

Windows Security Event ID 4624 (Logon), 4648 (Logon with explicit credentials)

Query — Splunk

1
2
3
4
5
6
7
index=wineventlog EventCode=4624
LogonType=3
AuthenticationPackageName=NTLM
| where NOT (SubjectUserName="-" AND WorkstationName="-")
| stats dc(ComputerName) as unique_targets by SubjectUserName, IpAddress
| where unique_targets > 5
| sort -unique_targets

Pass-the-Hash Indicators

  • Logon type 3 (network) with NTLM auth (Kerberos is normal — NTLM to multiple targets is not)
  • Same source IP authenticating to 5+ hosts within 30 minutes
  • Account is a service account or machine account (attackers often compromise these for stealth)
  • No corresponding interactive logon from the user on the source machine

Converting Hunts to Permanent Detections

Every completed hunt should produce either:

  1. A new SIEM alert rule — if the hunt found malicious activity or confirmed a viable detection pattern
  2. A baseline record — if the hunt found nothing, documenting what “normal” looks like for this technique in your environment
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def document_hunt_outcome(hunt_package, findings, new_rule=None):
    outcome = {
        'hunt_id':      hunt_package['hunt_id'],
        'technique':    hunt_package['mitre_technique'],
        'completed_at': datetime.utcnow().isoformat(),
        'findings':     len(findings),
        'escalated':    sum(1 for f in findings if f.get('escalated')),
        'detection_gap_closed': new_rule is not None,
        'rule_created': new_rule['rule_id'] if new_rule else None,
    }
    # Store in hunt register
    misp_create_event(
        title=f"Hunt Completed: {hunt_package['title']}",
        attributes=[{'type': 'text', 'value': str(outcome)}],
        tags=['hunt-register', hunt_package['mitre_technique']]
    )
    return outcome

Contact me at contact@malsayegh.ae to discuss building a structured hunting programme for your environment.

comments powered by Disqus
All rights Reserved for malsayegh.ae
Built with Hugo
Theme Stack designed by Jimmy