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:
- A new SIEM alert rule — if the hunt found malicious activity or confirmed a viable detection pattern
- 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.