SPLUNK
Splunk is a leading SIEM platform for log analysis and security monitoring. Essential for SOC analysts and threat hunters.
SEARCH BASICS#
SIMPLE SEARCH#
index=main # Search main index index=main error # Search for "error" index=main "failed login" # Exact phrase index=main error OR warning # OR search index=main error NOT debug # NOT search index=main error AND user=admin # AND search
TIME MODIFIERS#
earliest=-24h # Last 24 hours earliest=-7d latest=now # Last 7 days earliest=01/01/2024:00:00:00 # Specific start earliest=-1h@h # Last hour, rounded
FIELD SEARCHES#
index=main src_ip=192.168.1.100 index=main dest_port=443 index=main user=admin index=main status=404 index=main action=blocked
WILDCARDS#
index=main src_ip=192.168.1.* index=main user=admin* index=main host=web*
COMPARISON OPERATORS#
index=main status>400 # Greater than index=main status>=400 # Greater or equal index=main status<300 # Less than index=main status!=200 # Not equal index=main bytes>1000000 # Numeric comparison
SPL COMMANDS#
STATS#
| stats count # Count events | stats count by src_ip # Count by field | stats count by src_ip, dest_port # Count by multiple | stats sum(bytes) as total_bytes # Sum values | stats avg(response_time) # Average | stats min(bytes), max(bytes) # Min/Max | stats dc(user) as unique_users # Distinct count | stats values(dest_port) by src_ip # List values | stats earliest(_time), latest(_time) by user
TABLE#
| table src_ip, dest_ip, dest_port # Select columns | table _time, user, action # With timestamp
SORT#
| sort -count # Sort descending | sort +count # Sort ascending | sort -_time # Most recent first
TOP/RARE#
| top src_ip # Top 10 values | top 20 src_ip # Top 20 | top src_ip by dest_port # Top by field | rare dest_port # Least common
WHERE#
| where count > 100 | where src_ip="192.168.1.100" | where isnotnull(user) | where like(user, "admin%") | where match(url, "\.exe$")
EVAL#
| eval total=sent+received | eval status_type=if(status<400,"success","error") | eval mb=bytes/1024/1024 | eval time_diff=_time-start_time | eval domain=mvindex(split(email,"@"),1)
REX (REGEX EXTRACTION)#
| rex field=_raw "user=(?<username>\w+)" | rex field=url "\/(?<endpoint>[^\/]+)$" | rex field=message "IP:\s*(?<ip>\d+\.\d+\.\d+\.\d+)"
RENAME#
| rename src_ip as source_ip | rename count as total_count
DEDUP#
| dedup src_ip # Remove duplicates | dedup src_ip, dest_ip # By multiple fields
TIMECHART#
| timechart count # Count over time | timechart count by src_ip # By field | timechart span=1h count # Hourly buckets | timechart span=1d sum(bytes) # Daily totals
TRANSACTION#
| transaction user maxspan=30m # Group by user | transaction session_id # Group by session | transaction startswith="login" endswith="logout"
LOOKUP#
| lookup threat_intel ip as src_ip # Lookup table | lookup geo_ip ip as src_ip OUTPUT city, country
JOIN#
| join src_ip [search index=threats] | join type=left user [search index=hr_data]
SECURITY USE CASES#
FAILED LOGINS#
index=windows EventCode=4625 | stats count by Account_Name, src_ip | where count > 5
SUCCESSFUL LOGINS#
index=windows EventCode=4624 Logon_Type=10 | table _time, Account_Name, src_ip
BRUTE FORCE DETECTION#
index=windows EventCode=4625 | stats count by src_ip, Account_Name | where count > 10 | sort -count
ACCOUNT LOCKOUTS#
index=windows EventCode=4740 | table _time, Account_Name, Computer
NEW USER CREATED#
index=windows EventCode=4720 | table _time, Account_Name, Creator_Account
PASSWORD CHANGES#
index=windows EventCode=4723 OR EventCode=4724 | table _time, Account_Name, src_ip
PRIVILEGE ESCALATION#
index=windows EventCode=4672 | stats count by Account_Name | where Account_Name!="SYSTEM"
PROCESS CREATION#
index=sysmon EventCode=1 | table _time, User, ParentImage, Image, CommandLine
NETWORK CONNECTIONS#
index=sysmon EventCode=3 | stats count by Image, DestinationIp, DestinationPort | sort -count
POWERSHELL EXECUTION#
index=windows EventCode=4104 | table _time, ScriptBlockText | where len(ScriptBlockText) > 500
LATERAL MOVEMENT#
index=windows (EventCode=4624 Logon_Type=3) OR EventCode=4648 | stats count by src_ip, dest_ip, Account_Name
DNS QUERIES#
index=dns | stats count by query | sort -count
FIREWALL BLOCKS#
index=firewall action=blocked | stats count by src_ip, dest_port | sort -count
THREAT HUNTING#
BEACONING DETECTION#
index=proxy | bucket _time span=1m | stats count by src_ip, dest_ip, _time | stats stdev(count) as std, avg(count) as avg by src_ip, dest_ip | where std < 1 AND avg > 5
RARE PROCESSES#
index=sysmon EventCode=1 | rare Image | head 20
ENCODED POWERSHELL#
index=windows EventCode=4104 | where match(ScriptBlockText, "(?i)(encodedcommand|frombase64)") | table _time, Computer, ScriptBlockText
SUSPICIOUS PARENT-CHILD#
index=sysmon EventCode=1 | where ParentImage LIKE "%cmd.exe" AND Image LIKE "%powershell.exe" | table _time, User, ParentImage, Image, CommandLine
DATA EXFILTRATION#
index=proxy | stats sum(bytes_out) as total_out by src_ip, dest_ip | where total_out > 100000000 | sort -total_out
SUBSEARCHES#
index=main
[search index=threats
| fields ip
| rename ip as src_ip]
index=windows EventCode=4624
[search index=watchlist
| fields user
| rename user as Account_Name]
MACROS#
# Define in Settings > Advanced Search > Search Macros # Usage: `my_macro` `my_macro(arg1, arg2)`
ALERTS#
# Schedule search and trigger actions # Actions: Email, Webhook, Script, Notable Event
DASHBOARDS#
# Create visualizations # Panel types: Table, Chart, Map, Single Value
USEFUL FUNCTIONS#
| eval lower_user=lower(user) # Lowercase | eval upper_user=upper(user) # Uppercase | eval len=len(message) # Length | eval parts=split(url,"/") # Split string | eval domain=mvindex(parts,2) # Array index | eval now=now() # Current time | eval age=now()-_time # Time difference | eval ip_parts=split(src_ip,".") # IP parsing
QUICK REFERENCE#
index=main keyword # Basic search | stats count by field # Aggregate | table field1, field2 # Select columns | where condition # Filter | sort -field # Sort descending | top 10 field # Top values | timechart count # Time series | eval new_field=expression # Calculate | rex field=x "(?<name>regex)" # Extract | lookup table field # Enrich
SPLUNK CHEATSHEET
=================
Source: https://cheatsheet.johlem.net
Splunk is a leading SIEM platform for log analysis and security monitoring.
Essential for SOC analysts and threat hunters.
SEARCH BASICS
=============
SIMPLE SEARCH
-------------
index=main # Search main index
index=main error # Search for "error"
index=main "failed login" # Exact phrase
index=main error OR warning # OR search
index=main error NOT debug # NOT search
index=main error AND user=admin # AND search
TIME MODIFIERS
--------------
earliest=-24h # Last 24 hours
earliest=-7d latest=now # Last 7 days
earliest=01/01/2024:00:00:00 # Specific start
earliest=-1h@h # Last hour, rounded
FIELD SEARCHES
--------------
index=main src_ip=192.168.1.100
index=main dest_port=443
index=main user=admin
index=main status=404
index=main action=blocked
WILDCARDS
---------
index=main src_ip=192.168.1.*
index=main user=admin*
index=main host=web*
COMPARISON OPERATORS
--------------------
index=main status>400 # Greater than
index=main status>=400 # Greater or equal
index=main status<300 # Less than
index=main status!=200 # Not equal
index=main bytes>1000000 # Numeric comparison
SPL COMMANDS
============
STATS
-----
| stats count # Count events
| stats count by src_ip # Count by field
| stats count by src_ip, dest_port # Count by multiple
| stats sum(bytes) as total_bytes # Sum values
| stats avg(response_time) # Average
| stats min(bytes), max(bytes) # Min/Max
| stats dc(user) as unique_users # Distinct count
| stats values(dest_port) by src_ip # List values
| stats earliest(_time), latest(_time) by user
TABLE
-----
| table src_ip, dest_ip, dest_port # Select columns
| table _time, user, action # With timestamp
SORT
----
| sort -count # Sort descending
| sort +count # Sort ascending
| sort -_time # Most recent first
TOP/RARE
--------
| top src_ip # Top 10 values
| top 20 src_ip # Top 20
| top src_ip by dest_port # Top by field
| rare dest_port # Least common
WHERE
-----
| where count > 100
| where src_ip="192.168.1.100"
| where isnotnull(user)
| where like(user, "admin%")
| where match(url, "\.exe$")
EVAL
----
| eval total=sent+received
| eval status_type=if(status<400,"success","error")
| eval mb=bytes/1024/1024
| eval time_diff=_time-start_time
| eval domain=mvindex(split(email,"@"),1)
REX (REGEX EXTRACTION)
----------------------
| rex field=_raw "user=(?<username>\w+)"
| rex field=url "\/(?<endpoint>[^\/]+)$"
| rex field=message "IP:\s*(?<ip>\d+\.\d+\.\d+\.\d+)"
RENAME
------
| rename src_ip as source_ip
| rename count as total_count
DEDUP
-----
| dedup src_ip # Remove duplicates
| dedup src_ip, dest_ip # By multiple fields
TIMECHART
---------
| timechart count # Count over time
| timechart count by src_ip # By field
| timechart span=1h count # Hourly buckets
| timechart span=1d sum(bytes) # Daily totals
TRANSACTION
-----------
| transaction user maxspan=30m # Group by user
| transaction session_id # Group by session
| transaction startswith="login" endswith="logout"
LOOKUP
------
| lookup threat_intel ip as src_ip # Lookup table
| lookup geo_ip ip as src_ip OUTPUT city, country
JOIN
----
| join src_ip [search index=threats]
| join type=left user [search index=hr_data]
SECURITY USE CASES
==================
FAILED LOGINS
-------------
index=windows EventCode=4625
| stats count by Account_Name, src_ip
| where count > 5
SUCCESSFUL LOGINS
-----------------
index=windows EventCode=4624 Logon_Type=10
| table _time, Account_Name, src_ip
BRUTE FORCE DETECTION
---------------------
index=windows EventCode=4625
| stats count by src_ip, Account_Name
| where count > 10
| sort -count
ACCOUNT LOCKOUTS
----------------
index=windows EventCode=4740
| table _time, Account_Name, Computer
NEW USER CREATED
----------------
index=windows EventCode=4720
| table _time, Account_Name, Creator_Account
PASSWORD CHANGES
----------------
index=windows EventCode=4723 OR EventCode=4724
| table _time, Account_Name, src_ip
PRIVILEGE ESCALATION
--------------------
index=windows EventCode=4672
| stats count by Account_Name
| where Account_Name!="SYSTEM"
PROCESS CREATION
----------------
index=sysmon EventCode=1
| table _time, User, ParentImage, Image, CommandLine
NETWORK CONNECTIONS
-------------------
index=sysmon EventCode=3
| stats count by Image, DestinationIp, DestinationPort
| sort -count
POWERSHELL EXECUTION
--------------------
index=windows EventCode=4104
| table _time, ScriptBlockText
| where len(ScriptBlockText) > 500
LATERAL MOVEMENT
----------------
index=windows (EventCode=4624 Logon_Type=3) OR EventCode=4648
| stats count by src_ip, dest_ip, Account_Name
DNS QUERIES
-----------
index=dns
| stats count by query
| sort -count
FIREWALL BLOCKS
---------------
index=firewall action=blocked
| stats count by src_ip, dest_port
| sort -count
THREAT HUNTING
==============
BEACONING DETECTION
-------------------
index=proxy
| bucket _time span=1m
| stats count by src_ip, dest_ip, _time
| stats stdev(count) as std, avg(count) as avg by src_ip, dest_ip
| where std < 1 AND avg > 5
RARE PROCESSES
--------------
index=sysmon EventCode=1
| rare Image
| head 20
ENCODED POWERSHELL
------------------
index=windows EventCode=4104
| where match(ScriptBlockText, "(?i)(encodedcommand|frombase64)")
| table _time, Computer, ScriptBlockText
SUSPICIOUS PARENT-CHILD
-----------------------
index=sysmon EventCode=1
| where ParentImage LIKE "%cmd.exe" AND Image LIKE "%powershell.exe"
| table _time, User, ParentImage, Image, CommandLine
DATA EXFILTRATION
-----------------
index=proxy
| stats sum(bytes_out) as total_out by src_ip, dest_ip
| where total_out > 100000000
| sort -total_out
SUBSEARCHES
===========
index=main
[search index=threats
| fields ip
| rename ip as src_ip]
index=windows EventCode=4624
[search index=watchlist
| fields user
| rename user as Account_Name]
MACROS
======
# Define in Settings > Advanced Search > Search Macros
# Usage:
`my_macro`
`my_macro(arg1, arg2)`
ALERTS
======
# Schedule search and trigger actions
# Actions: Email, Webhook, Script, Notable Event
DASHBOARDS
==========
# Create visualizations
# Panel types: Table, Chart, Map, Single Value
USEFUL FUNCTIONS
================
| eval lower_user=lower(user) # Lowercase
| eval upper_user=upper(user) # Uppercase
| eval len=len(message) # Length
| eval parts=split(url,"/") # Split string
| eval domain=mvindex(parts,2) # Array index
| eval now=now() # Current time
| eval age=now()-_time # Time difference
| eval ip_parts=split(src_ip,".") # IP parsing
QUICK REFERENCE
---------------
index=main keyword # Basic search
| stats count by field # Aggregate
| table field1, field2 # Select columns
| where condition # Filter
| sort -field # Sort descending
| top 10 field # Top values
| timechart count # Time series
| eval new_field=expression # Calculate
| rex field=x "(?<name>regex)" # Extract
| lookup table field # Enrich
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.