ELASTIC/ELK STACK
ELK Stack (Elasticsearch, Logstash, Kibana) for log analysis. Essential for SIEM functionality and security monitoring.
ELASTICSEARCH QUERIES#
BASIC SEARCH#
# Match all
GET /index/_search
{
"query": { "match_all": {} }
}
# Match query
GET /index/_search
{
"query": {
"match": { "message": "error" }
}
}
# Term query (exact match)
GET /index/_search
{
"query": {
"term": { "status": "404" }
}
}
BOOLEAN QUERIES#
GET /index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "event.action": "login" } }
],
"must_not": [
{ "term": { "user.name": "system" } }
],
"filter": [
{ "range": { "@timestamp": { "gte": "now-1h" } } }
]
}
}
}
RANGE QUERIES#
GET /index/_search
{
"query": {
"range": {
"@timestamp": {
"gte": "now-24h",
"lte": "now"
}
}
}
}
WILDCARD/REGEX#
GET /index/_search
{
"query": {
"wildcard": { "host.name": "web*" }
}
}
GET /index/_search
{
"query": {
"regexp": { "url.path": "/api/v[0-9]+/.*" }
}
}
AGGREGATIONS#
TERMS AGGREGATION#
GET /index/_search
{
"size": 0,
"aggs": {
"by_status": {
"terms": { "field": "http.response.status_code" }
}
}
}
DATE HISTOGRAM#
GET /index/_search
{
"size": 0,
"aggs": {
"events_over_time": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1h"
}
}
}
}
CARDINALITY#
GET /index/_search
{
"size": 0,
"aggs": {
"unique_ips": {
"cardinality": { "field": "source.ip" }
}
}
}
KQL (KIBANA QUERY LANGUAGE)#
BASIC SYNTAX#
message: error # Field contains message: "exact phrase" # Exact phrase status: 404 # Numeric host.name: web* # Wildcard
OPERATORS#
message: error AND status: 500 # AND message: error OR message: warning # OR NOT status: 200 # NOT status: (200 OR 201 OR 204) # Group
RANGES#
http.response.status_code >= 400 http.response.status_code: [400 TO 599] @timestamp >= "2024-01-01"
WILDCARDS#
host.name: web* # Starts with url.path: */admin/* # Contains
EXISTS#
user.name: * # Field exists NOT user.name: * # Field missing
SECURITY QUERIES#
FAILED LOGINS#
event.action: "authentication_failure" AND event.outcome: "failure"
SUCCESSFUL LOGINS#
event.action: "authentication_success" AND winlog.event_id: 4624
POWERSHELL EXECUTION#
process.name: "powershell.exe" AND process.command_line: *encoded*
NETWORK CONNECTIONS#
event.category: "network" AND destination.port: (4444 OR 5555 OR 8888)
PROCESS CREATION#
event.category: "process" AND event.type: "start"
FILE CREATION#
event.category: "file" AND event.type: "creation"
LATERAL MOVEMENT#
winlog.event_id: 4624 AND winlog.event_data.LogonType: 3
PRIVILEGE ESCALATION#
winlog.event_id: 4672
DNS QUERIES#
dns.question.name: *
BRUTE FORCE#
# In Kibana, use aggregations event.action: "authentication_failure" | stats count by source.ip | where count > 10
ECS (ELASTIC COMMON SCHEMA)#
COMMON FIELDS#
@timestamp Event timestamp event.category Category (authentication, network, etc.) event.type Type (start, end, info, etc.) event.action Specific action event.outcome Success/failure source.ip Source IP source.port Source port destination.ip Destination IP destination.port Destination port user.name Username host.name Hostname process.name Process name process.pid Process ID process.command_line Command line file.name File name file.path File path
WINDOWS EVENTS#
winlog.event_id Windows Event ID winlog.channel Log channel winlog.event_data.* Event-specific data
LOGSTASH FILTERS#
GROK PATTERNS#
filter {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:host} %{WORD:program}: %{GREEDYDATA:message}" }
}
}
COMMON PATTERNS#
%{IP:client_ip}
%{WORD:word}
%{NUMBER:num}
%{GREEDYDATA:data}
%{TIMESTAMP_ISO8601:timestamp}
%{SYSLOGTIMESTAMP:syslog_timestamp}
%{COMBINEDAPACHELOG}
MUTATE#
filter {
mutate {
rename => { "old_field" => "new_field" }
remove_field => [ "unwanted" ]
add_field => { "new" => "value" }
lowercase => [ "field" ]
}
}
DATE#
filter {
date {
match => [ "timestamp", "ISO8601", "yyyy-MM-dd HH:mm:ss" ]
target => "@timestamp"
}
}
GEOIP#
filter {
geoip {
source => "client_ip"
target => "geoip"
}
}
INDEX MANAGEMENT#
LIST INDICES#
GET /_cat/indices?v
INDEX PATTERN#
# In Kibana: Stack Management > Index Patterns
CREATE INDEX#
PUT /my-index
DELETE INDEX#
DELETE /my-index
INDEX LIFECYCLE#
# Hot -> Warm -> Cold -> Delete
DETECTION RULES#
KIBANA DETECTION#
# Security > Detections > Rules
RULE TYPES#
Custom query KQL/EQL query Machine learning Anomaly detection Threshold Count-based Event correlation EQL sequence
EQL (EVENT QUERY LANGUAGE)#
BASIC SYNTAX#
process where process.name == "powershell.exe"
SEQUENCE#
sequence by host.id [process where process.name == "cmd.exe"] [process where process.name == "powershell.exe"]
WITH MAXSPAN#
sequence by host.id with maxspan=5m [authentication where event.outcome == "failure"] with runs=5 [authentication where event.outcome == "success"]
API EXAMPLES#
CURL#
# Search
curl -X GET "localhost:9200/index/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} }
}'
# Index document
curl -X POST "localhost:9200/index/_doc" -H 'Content-Type: application/json' -d'
{
"field": "value"
}'
QUICK REFERENCE#
# KQL field: value # Match field: "exact phrase" # Phrase field: val* # Wildcard field: (a OR b) # OR field: value AND other: val # AND NOT field: value # NOT field >= 100 # Range # Common searches event.action: "login" AND event.outcome: "failure" process.name: "powershell.exe" destination.port: (4444 OR 5555) winlog.event_id: 4624
ELASTIC/ELK STACK CHEATSHEET
============================
Source: https://cheatsheet.johlem.net
ELK Stack (Elasticsearch, Logstash, Kibana) for log analysis.
Essential for SIEM functionality and security monitoring.
ELASTICSEARCH QUERIES
=====================
BASIC SEARCH
------------
# Match all
GET /index/_search
{
"query": { "match_all": {} }
}
# Match query
GET /index/_search
{
"query": {
"match": { "message": "error" }
}
}
# Term query (exact match)
GET /index/_search
{
"query": {
"term": { "status": "404" }
}
}
BOOLEAN QUERIES
---------------
GET /index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "event.action": "login" } }
],
"must_not": [
{ "term": { "user.name": "system" } }
],
"filter": [
{ "range": { "@timestamp": { "gte": "now-1h" } } }
]
}
}
}
RANGE QUERIES
-------------
GET /index/_search
{
"query": {
"range": {
"@timestamp": {
"gte": "now-24h",
"lte": "now"
}
}
}
}
WILDCARD/REGEX
--------------
GET /index/_search
{
"query": {
"wildcard": { "host.name": "web*" }
}
}
GET /index/_search
{
"query": {
"regexp": { "url.path": "/api/v[0-9]+/.*" }
}
}
AGGREGATIONS
============
TERMS AGGREGATION
-----------------
GET /index/_search
{
"size": 0,
"aggs": {
"by_status": {
"terms": { "field": "http.response.status_code" }
}
}
}
DATE HISTOGRAM
--------------
GET /index/_search
{
"size": 0,
"aggs": {
"events_over_time": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1h"
}
}
}
}
CARDINALITY
-----------
GET /index/_search
{
"size": 0,
"aggs": {
"unique_ips": {
"cardinality": { "field": "source.ip" }
}
}
}
KQL (KIBANA QUERY LANGUAGE)
===========================
BASIC SYNTAX
------------
message: error # Field contains
message: "exact phrase" # Exact phrase
status: 404 # Numeric
host.name: web* # Wildcard
OPERATORS
---------
message: error AND status: 500 # AND
message: error OR message: warning # OR
NOT status: 200 # NOT
status: (200 OR 201 OR 204) # Group
RANGES
------
http.response.status_code >= 400
http.response.status_code: [400 TO 599]
@timestamp >= "2024-01-01"
WILDCARDS
---------
host.name: web* # Starts with
url.path: */admin/* # Contains
EXISTS
------
user.name: * # Field exists
NOT user.name: * # Field missing
SECURITY QUERIES
================
FAILED LOGINS
-------------
event.action: "authentication_failure" AND event.outcome: "failure"
SUCCESSFUL LOGINS
-----------------
event.action: "authentication_success" AND winlog.event_id: 4624
POWERSHELL EXECUTION
--------------------
process.name: "powershell.exe" AND process.command_line: *encoded*
NETWORK CONNECTIONS
-------------------
event.category: "network" AND destination.port: (4444 OR 5555 OR 8888)
PROCESS CREATION
----------------
event.category: "process" AND event.type: "start"
FILE CREATION
-------------
event.category: "file" AND event.type: "creation"
LATERAL MOVEMENT
----------------
winlog.event_id: 4624 AND winlog.event_data.LogonType: 3
PRIVILEGE ESCALATION
--------------------
winlog.event_id: 4672
DNS QUERIES
-----------
dns.question.name: *
BRUTE FORCE
-----------
# In Kibana, use aggregations
event.action: "authentication_failure"
| stats count by source.ip
| where count > 10
ECS (ELASTIC COMMON SCHEMA)
===========================
COMMON FIELDS
-------------
@timestamp Event timestamp
event.category Category (authentication, network, etc.)
event.type Type (start, end, info, etc.)
event.action Specific action
event.outcome Success/failure
source.ip Source IP
source.port Source port
destination.ip Destination IP
destination.port Destination port
user.name Username
host.name Hostname
process.name Process name
process.pid Process ID
process.command_line Command line
file.name File name
file.path File path
WINDOWS EVENTS
--------------
winlog.event_id Windows Event ID
winlog.channel Log channel
winlog.event_data.* Event-specific data
LOGSTASH FILTERS
================
GROK PATTERNS
-------------
filter {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:host} %{WORD:program}: %{GREEDYDATA:message}" }
}
}
COMMON PATTERNS
---------------
%{IP:client_ip}
%{WORD:word}
%{NUMBER:num}
%{GREEDYDATA:data}
%{TIMESTAMP_ISO8601:timestamp}
%{SYSLOGTIMESTAMP:syslog_timestamp}
%{COMBINEDAPACHELOG}
MUTATE
------
filter {
mutate {
rename => { "old_field" => "new_field" }
remove_field => [ "unwanted" ]
add_field => { "new" => "value" }
lowercase => [ "field" ]
}
}
DATE
----
filter {
date {
match => [ "timestamp", "ISO8601", "yyyy-MM-dd HH:mm:ss" ]
target => "@timestamp"
}
}
GEOIP
-----
filter {
geoip {
source => "client_ip"
target => "geoip"
}
}
INDEX MANAGEMENT
================
LIST INDICES
------------
GET /_cat/indices?v
INDEX PATTERN
-------------
# In Kibana: Stack Management > Index Patterns
CREATE INDEX
------------
PUT /my-index
DELETE INDEX
------------
DELETE /my-index
INDEX LIFECYCLE
---------------
# Hot -> Warm -> Cold -> Delete
DETECTION RULES
===============
KIBANA DETECTION
----------------
# Security > Detections > Rules
RULE TYPES
----------
Custom query KQL/EQL query
Machine learning Anomaly detection
Threshold Count-based
Event correlation EQL sequence
EQL (EVENT QUERY LANGUAGE)
==========================
BASIC SYNTAX
------------
process where process.name == "powershell.exe"
SEQUENCE
--------
sequence by host.id
[process where process.name == "cmd.exe"]
[process where process.name == "powershell.exe"]
WITH MAXSPAN
------------
sequence by host.id with maxspan=5m
[authentication where event.outcome == "failure"] with runs=5
[authentication where event.outcome == "success"]
API EXAMPLES
============
CURL
----
# Search
curl -X GET "localhost:9200/index/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} }
}'
# Index document
curl -X POST "localhost:9200/index/_doc" -H 'Content-Type: application/json' -d'
{
"field": "value"
}'
QUICK REFERENCE
---------------
# KQL
field: value # Match
field: "exact phrase" # Phrase
field: val* # Wildcard
field: (a OR b) # OR
field: value AND other: val # AND
NOT field: value # NOT
field >= 100 # Range
# Common searches
event.action: "login" AND event.outcome: "failure"
process.name: "powershell.exe"
destination.port: (4444 OR 5555)
winlog.event_id: 4624
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.