[Date]
Notes for SPLUNK
BY USING HOME LAB
MERROUNI HAMID
Contents
I. Lab Preparation and how does spluk work: ................................................................................2
Install a Windows universal forwarder ...................................................................................3
Install a *nix universal forwarder ...........................................................................................3
How Data Travels Through Splunk: .........................................................................................3
What’s an index : ....................................................................................................................4
splunk config file .....................................................................................................................4
Enable a Receiver for Splunk Enterprise: .................................................................................5
Shipping Windows Event Logs to Splunk .................................................................................6
Creating a Test Index ..............................................................................................................6
II. Data Onboarding: .......................................................................................................................6
III. Basic SPL Splunk Processing Language : ..................................................................................7
IV. File Lookups: ......................................................................................................................... 18
V. Visualizations and Dashboards: ................................................................................................ 24
1. Visualizations: ...................................................................................................................... 24
2. Classic Dashboard ................................................................................................................. 27
3. building a dynamic Dashboard by token .............................................................................. 30
VI. Data models: ........................................................................................................................ 32
VII. Using Search to Find Suspicious Events: ............................................................................... 36
1. HTTP Connections to a Server by IP (Conditional Eval) .......................................................... 36
2. Searching 2 Data Sources for a Common Indicator (Using OR) ............................................. 37
3. Finding Traces of Look-a-like Domains (Using fuzzylookup).................................................. 38
4. Using Geolocation to Find Anomalous Connections .............................................................. 40
5. first Time Login of a User on a Machine ................................................................................ 41
6. Identifying Password Guessing Attempts with Failed and Successful Logins ........................ 42
7. Identifying High Network Bandwidth Consumption from a Baseline .................................... 44
1
I. Lab Preparation and how does spluk work:
In this lab you will learn the installation and configuration of splunk in windows and linux
Search to download splunk and login in the page splunk.com
We download the version of splunk of system we will use ( I use my windows host to make splunk
work butter , but you can use any system ( windows , linux or macOS) in VM or host , there are no
different
2
Install a Windows universal forwarder
https://docs.splunk.com/Documentation/Forwarder/9.2.0/Forwarder/InstallaWindowsunivers
alforwarderfromaninstaller#:~:text=Download%20the%20universal%20forwarder%20from,Spl
unk%20Enterprise%20or%20Splunk%20Cloud.
Install a *nix universal forwarder
https://docs.splunk.com/Documentation/Forwarder/9.2.0/Forwarder/Installanixuniversalforw
arder
typical architecture of splunk :
How Data Travels Through Splunk:
3
What’s an index :
an index is a repository or storage location where Splunk stores and manages data. When data is
ingested into Splunk, it is indexed and stored in these index locations. Indexes serve as the
foundation for searching, analyzing, and visualizing data within Splunk
splunk config file
the config file in linux and windows are the same way
but root splunk folder in linux : /opt/splunk
and window : C:\Program Files\Splunk
4
Enable a Receiver for Splunk Enterprise:
go to setting in splunk enterprise :
we click on forwarding and receiving then receive data :
We input the port that we want and save the settings
5
Shipping Windows Event Logs to Splunk
https://docs.splunk.com/Documentation/Splunk/9.2.1/Data/MonitorWindowseventlogdata#:~:text=
To%20monitor%20Windows%20Event%20Log,data%20into%20Splunk%20Cloud%20Platform.
Creating a Test Index
https://docs.splunk.com/Documentation/Splunk/9.2.0/Data/Useatestindex
II. Data Onboarding:
https://docs.splunk.com/Documentation/Splunk/latest/Deploy/Distributedoverview
https://docs.splunk.com/Documentation/Splunk/latest/DistSearch/Whatisdistributedsearch
https://docs.splunk.com/Documentation/Splunk/latest/Deploy/Datapipeline
https://docs.splunk.com/Documentation/Splunk/latest/Indexer/Aboutindexesandindexers
https://docs.splunk.com/Documentation/Splunk/latest/Indexer/Aboutmanagingindexes
https://docs.splunk.com/Documentation/Splunk/latest/Forwarding/Enableareceiver
https://docs.splunk.com/Documentation/Splunk/latest/Admin/Aboutconfigurationfiles
https://docs.splunk.com/Documentation/Splunk/latest/Admin/Wheretofindtheconfigurationfiles
https://docs.splunk.com/Documentation/Splunk/latest/Admin/Listofconfigurationfiles
https://docs.splunk.com/Documentation/Splunk/latest/Admin/Whatsanapp
https://docs.splunk.com/Documentation/Splunk/latest/Data/MonitorWindowseventlogdata
6
III. Basic SPL Splunk Processing Language :
Botv2: A sample security dataset and CTF platform for information security professionals,
researchers, students, and enthusiasts. This page hosts information regarding the version 2 dataset
To download : https://github.com/splunk/botsv2
How to download : https://edscybersec.com/posts/installing-splunk-botsv2-dataset/
The same way in linux and windows
Basic search components :
7
index=botsv2 earliest=0 sourcetype="stream:http" |stats count by host
this command use for count the satastics by host from the index botsv2 source stream:http
index=botsv2 earliest=0 sourcetype="stream:http" |eval src_ip_port = src_ip.":".src_port
command eval use to create a new field by combinations of another field
8
index=botsv2 earliest=0 sourcetype="stream:http" |table src_ip, dest_ip, dest_port
Command table use to create table of the fields those we are choosing
index=botsv2 earliest=0 sourcetype="stream:http"
| stats dc(src_port) as number_of_connection by src_ip, dest_ip, dest_port
| table src_ip dest_ip , number_of_connection
Function dc calculates the number of distinct source ports (src_port) for each combination of src_ip,
dest_ip, and dest_port
9
index=botsv2 earliest=0 sourcetype="stream:http"
|eval mb =bytes/(1024*1024)
|timechart span=1d sum(mb) as total_mb
eval mb = bytes/(1024*1024): Calculates the total megabytes transferred by dividing the bytes field
by 1024*1024.
timechart span=1d sum(mb) as total_mb: Aggregates the data over each day (span=1d) and sums up
the total megabytes transferred (sum(mb)), creating a timechart.
We can use with span function s,m,h,d,w,mon and y for specific the duration of time
index=botsv2 earliest=0 sourcetype="stream:http" |where bytes_out > bytes_in
where bytes_out > bytes_in: Filters events where the number of bytes sent out (bytes_out) is
greater than the number of bytes received (bytes_in).
10
index=botsv2 earliest=0 sourcetype="stream:http"
| rex field=http_user_agent "Windows\s+NT\s+(?<win_nt_version>[\d\.]+)"
rex field=http_user_agent "Windows\s+NT\s+(?<win_nt_version>[\d\.]+)": Uses regular expression
to extract the version of Windows NT from the http_user_agent field and captures it into a new field
called win_nt_version. The regular expression Windows\s+NT\s+(?<win_nt_version>[\d\.]+)
matches "Windows", followed by "NT", then captures the version number consisting of digits and
periods ([\d\.]+).
This query should help you extract and identify the version of Windows NT from the user-agent
strings in your HTTP stream events.
11
index=botsv2 earliest=0 sourcetype="stream:http"
| stats sum(bytes_in) AS bytes_in, sum(bytes_out) AS bytes_out BY src_ip, dest_ip
| eval mbytes_in = round(bytes_in/pow(1024,2),2), mbytes_out =
round(bytes_out/pow(1024,2),2) | fields - bytes_in, bytes_out
| stats avg(mbytes_in) AS avg_mbytes_in, avg(mbytes_out) AS avg_mbytes_out
| eval mbytes_in = round(bytes_in/pow(1024,2),2), mbytes_out =
round(bytes_out/pow(1024,2),2): Converts the sum of bytes into megabytes and rounds the result
to two decimal places.
| fields - bytes_in, bytes_out: Removes the original bytes_in and bytes_out fields, leaving only the
mbytes_in and mbytes_out fields.
| stats avg(mbytes_in) AS avg_mbytes_in, avg(mbytes_out) AS avg_mbytes_out: Calculates the
average megabytes transferred for each source-destination IP pair.
| sort - mbytes_in: Sorts the results based on the average megabytes transferred in descending
order.
This query provides insights into the average megabytes transferred between source and destination
IP pairs, sorted by the average megabytes in descending order.
12
index=botsv2 earliest=0 sourcetype="stream:http" | stats list(http_method) AS http_methods
stats list(http_method) AS http_methods: Calculates a list of unique values of the http_method field
across all events and assigns it to a new field named http_methods.
This query will give you a list of unique HTTP methods present in the dataset.
index=botsv2 earliest=0 sourcetype="stream:http"
|stats values(http_method) AS http_methods
stats values(http_method) AS http_methods: Calculates a list of unique values of the http_method
field across all events and assigns it to a new field named http_methods.
13
index=botsv2 earliest=0 sourcetype="stream:http"
| eval ua_length = len(http_user_agent)
| stats min(ua_length) AS min, max(ua_length) AS max, avg(ua_length) AS avg
eval ua_length = len(http_user_agent): Calculates the length of the http_user_agent field for
each event and assigns it to a new field named ua_length.
stats min(ua_length) AS min, max(ua_length) AS max, avg(ua_length) AS avg: Calculates the
minimum, maximum, and average length of the http_user_agent field across all events.
This query will provide you with statistics regarding the length of the http_user_agent field, including
the minimum, maximum, and average lengths.
index=botsv2 earliest=0 sourcetype="stream:http" | eval ua_length = len(http_user_agent)
| eventstats min(ua_length) AS min, max(ua_length) AS max, avg(ua_length) AS avg
| where ua_length=min OR ua_length=max
| eventstats min(ua_length) AS min, max(ua_length) AS max, avg(ua_length) AS avg: Uses
eventstats to compute the minimum, maximum, and average length of the http_user_agent field
across all events.
14
index=botsv2 earliest=0 sourcetype="stream:http" | streamstats count | table count, _raw
| streamstats count: Uses streamstats to calculate the count of events encountered so far.
This query will give you a table showing the count of events encountered so far along with the
corresponding raw event data.
index=botsv2 earliest=0 sourcetype="stream:http" | chart count BY http_method host
| chart count BY http_method host: This part of the query utilizes the chart command to create a
chart where the x-axis represents the unique values of the http_method field, the y-axis represents
the count of events for each method, and each series in the chart represents a different value of the
host field.
This chart provides a visual representation of the distribution of HTTP methods across different hosts
in your dataset. It allows you to quickly analyze which HTTP methods are more commonly used on
which hosts.
15
index=botsv2 earliest=0 sourcetype="stream:http"
| lookup apache_httpstatus_lookup status as http_status
| lookup apache_httpstatus_lookup status as http_status: Performs a lookup operation using the
apache_httpstatus_lookup table on the http_status field in your events. It attempts to match the
values of the http_status field in your events with the values of the status field in the lookup table.
| inputlookup apache_httpstatus_lookup
| inputlookup apache_httpstatus_lookup: This command reads the contents of the lookup table
named apache_httpstatus_lookup and presents the data as search results.
This command is useful for viewing the contents of a lookup table directly within your search
interface, which can be helpful for debugging or inspecting the data in the lookup table.
16
| inputlookup apache_httpstatus_lookup
| append
[ makeresults
| eval status=418, status_description="I'm a teapot", status_type="Client Error" ]
| fields - _time
| outputlookup apache_httpstatus_lookup
| append [ makeresults | eval status=418, status_description="I'm a teapot", status_type="Client
Error" ]: This appends a new entry to the results retrieved from the apache_httpstatus_lookup table.
The new entry has a status of 418, a status description of "I'm a teapot", and a status type of "Client
Error".
| fields - _time: This command removes the _time field from the events, as it's not necessary for the
lookup table.
| outputlookup apache_httpstatus_lookup: Finally, this command writes the combined results
(original lookup table plus the new entry) back to the apache_httpstatus_lookup lookup table.
In summary, this query adds a new entry to the apache_httpstatus_lookup lookup table with the
status code 418, a custom status description, and a status type. It then updates the lookup table with
this new entry.
17
IV. File Lookups:
1. CSV file Lookups
file located in the search head
lives either in the app’s lookups folder or /etc/system/lookups
In cmd : ~/splunk/etc/apps
mkdir well_known_ports
mkdir metadata
notpade default.meta
mkdir lookups
cd lookups
notepad well_known_ports.csv
mkdir default
cd default
notepad transforms.conf
18
http://localhost:8000/en-US/debug/refresh
index=botsv2 sourcetype="pan:traffic" earliest=0
| lookup well_known_ports port AS dest_port, transport
| table src_ip, dest_ip, dest_port, transport, description
| lookup well_known_ports port AS dest_port, transport: Performs a lookup operation using the
well_known_ports lookup table. It matches the dest_port field from the events with the port field in
the well_known_ports table and retrieves the corresponding transport field.
This query helps to enrich the traffic events with additional information about the destination ports,
including the transport protocol and a description of the service associated with each port
19
2. KV Store Lookups:
Splunk comes with a instance of MongoDB
Great large of lookups or when data is updated often
In cmd : ~/splunk/etc/apps/well_known_ports/default:
notepad collections.conf
notepad transforms.conf
http://localhost:8000/en-US/debug/refresh
| makeresults
| eval port="443", transport="tcp", description="https"
| append
[| makeresults
| eval port="123", transport="udp", description="ntp"]
| append
[| makeresults
| eval port="53", transport="udp", description="ssh"]
| fields - _time
| outputlookup well_known_ports_kv
20
21
3. External Lookups:
Uses a python script or binary to fetch data from an external source
Exemple: Built-in dnslookup
In cmd ~ \etc\system\default
notepad transforms.conf
We can see exemple of external lookups in pythom scripts in transforms.conf
We can find the external_looukus.py exist in ~/etc/system/bin
22
index=botsv2 sourcetype="pan:traffic" earliest=0 site="bea4.cnn.com"
| lookup dnslookup clienthost AS site
4. Automatic Lookups:
Go to ~\etc\apps\well_known_ports\default
notepad props.conf
refresh by : http://localhost:8000/en-US/debug/refresh
you will find now the field description without use command lookup
23
V. Visualizations and Dashboards:
1. Visualizations:
index=botsv2 sourcetype="stream:http" earliest=08/30/2017:00:00:00 latest=09/01/2017:00:00:00
http_user_agent=* | stats count by http_user_agent
by using bie chart
24
by using single value with stats command
By using single value with timechart command
25
index=botsv2 sourcetype="pan:traffic" earliest=08/30/2017:00:00:00
latest=09/01/2017:00:00:00
| iplocation dest_ip
| stats count by Country
| geom geo_countries allFeatures=True featureIdField=Country
| iplocation dest_ip: This command performs IP geolocation on the destination IP addresses found in
the events.
| stats count by Country: This command counts the occurrences of events for each country.
| geom geo_countries allFeatures=True featureIdField=Country: This command visualizes the counts
on a map, using the country as the feature identifier.
26
2. Classic Dashboard
index=botsv2 sourcetype="pan:traffic" earliest=08/30/2017:00:00:00
latest=09/01/2017:00:00:00
| stats count BY src_ip
| sort -count
We can create a new dashboard with click in save as new dashboard
We write a new name for it and we can change its permissions if we want ,Then we can save it
27
we will get the dashboard above with table of src_ip
also we can add a more content from anther searches into this dashboard
such as statistic of destinations ip by count but before that we will use save as existing dashboard
28
we will find the second table below the first table, but will do some edits to obtain the dashboard
more former .Also ,we will add another contents , the first the timechat by dest port , and table of
statistic by source and destination interface
29
3. building a dynamic Dashboard by token
by using the dashboard we was creating before , we click on edit and add input “text”
After that, we click on the pen icon and input the information as shown in the image below
then we wil do the same in destination ip :
30
we will click in seacrh icon from each the four panel and add $src_ip_tok$ $dest_ip_tok$ and click on
Apply , then we will save all edits
finaly, we can write whice IP we want to show stastics of her in Dashboard (we can use destantion ip
,source ip or the both of then in the same time ) , the exemple below we show all stastic of conection
from all IPs to 8.8.8.8
31
VI. Data models:
A data model is a collection of important fields for a certain topic:
Network traffic will always have a source and a destination address
Data models have knowledge about the data built-in:
Some authentication events are created by logins with privileged accounts
Data models are hierarchical (datasets):
A subset of all web traffic events may come from proxy servers
Data models are like looking at your data if it was a relational database (columns and
rows)
We can use gui by click on settings then data models
we will find a lot of data models we can chose for exmple the network trafic from the second page
after that , we click on pivot then all trafic
32
we can choose fields now , for exmple destination ip :
we can visualite data , thiss all without using SPL query
33
we can also use data models in bar of search
we can select which data model we want by click in or by using saerch
| datamodel Network_Traffic search
34
| datamodel Network_Traffic search
| stats count BY All_Traffic.dest_ip
35
VII. Using Search to Find Suspicious Events:
1. HTTP Connections to a Server by IP (Conditional Eval)
Searching for connections using the IP directly:
index=botsv2 sourcetype=stream:http earliest=08/30/2017:00:00:00
latest=09/01/2017:00:00:00
| eval isip = if(match(site,"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"),1,0)
| search isip=1
| stats count BY src_ip
| sort -count
| eval isip = if(match(site,"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"),1,0): This evaluates whether
the "site" field contains an IP address using a regular expression. If an IP address is found, it
assigns 1 to the field "isip"; otherwise, it assigns 0.
| search isip=1: This filters out events where "isip" is equal to 1, meaning that the "site" field
contains an IP address.
36
2. Searching 2 Data Sources for a Common Indicator (Using OR)
Using OR to combine the datasets (Searching in stream:http and stream:dns):
index=botsv2 (sourcetype=stream:http site="uranus.frothly.local:8014") OR
(sourcetype=stream:dns query{}="uranus.frothly.local") earliest=08/20/2017:00:00:00
latest=09/01/2017:00:00:00
| eval site = replace(site,"(.*):\d+","\1")
| eval dest_host = if(sourcetype=="stream:http",site,'query{}')
| search dest_host="uranus.frothly.local"
| stats count values(sourcetype) AS sourcetype BY src_ip, dest_host
| sort -count
eval site = replace(site,"(.*):\d+","\1"): This uses the eval command to create a new field "site" by
removing the port number from the "site" field.
replace(site,"(.*):\d+","\1"): This is the function used to modify the "site" field. It's a regular
expression-based replacement function.
(.*):\d+: This is a regular expression pattern. Let's break it down:
.*: This matches any character (except for line terminators) zero or more times.
Essentially, it matches any sequence of characters.
:: This matches the colon character.
\d+: This matches one or more digits.
\1: This is a backreference in the replacement string. It refers to the first captured group (.*):,
which is everything before the colon. So essentially, it replaces the entire match
eval dest_host = if(sourcetype=="stream:http",site,'query{}'): This creates a new field "dest_host". If
the sourcetype is "stream:http", it uses the "site" field; otherwise, it uses the "query{}" field.
Overall, this query is designed to search for events related to the "uranus.frothly.local" host within
the specified time range and analyze the counts and types of those events based on the source IP
address.
37
3. Finding Traces of Look-a-like Domains (Using fuzzylookup)
Calculating the Levenshtein Distanc:
index=botsv2 (sourcetype=stream:smtp sender_domain=*) OR (sourcetype=stream:dns
query{}=*) OR (sourcetype=stream:http site=*) earliest=1
| eval maybe_evil_domain = coalesce(sender_domain,'query{}',site)
| stats count BY maybe_evil_domain, sourcetype
| fuzzylookup addmetrics=true our_domains domains AS maybe_evil_domain
| search fuzzy_score < 3
| table domains maybe_evil_domain fuzzy_score fuzzy_similarity sourcetype
First, we need to instal Fuzzylookup in splunk enterprise , then we will create file lookups her name is
our_domain (we flow the same steps of creation CSV file lookups)
38
uzzylookup addmetrics=true our_domains domains AS maybe_evil_domain: This command
performs a fuzzy lookup against a list of known "safe" domains. Here's what each part does:
fuzzylookup: This command performs a fuzzy lookup operation.
addmetrics=true: This parameter specifies that additional metrics should be added
to the results.
our_domains: This likely represents a list of known-safe domains maintained by the
organization.
domains AS maybe_evil_domain: This specifies the field from the fuzzy lookup
results to be compared against the maybe_evil_domain field from the original data.
search fuzzy_score < 3: This line filters the results to only include matches where the fuzzy score (a
measure of similarity between strings) is less than 3. This implies that the domains being compared
are quite different from the known-good domains.
this query is designed to identify potentially malicious domains by comparing them against a list of
known-safe domains. It calculates similarity scores between potentially malicious domains and
known-safe domains using fuzzy matching and filters the results to only show domains with low
similarity scores. The results are then presented in a table format for further analysis.
39
4. Using Geolocation to Find Anomalous Connections
Finding the Rarest Countries in Connection Events:
index=botsv2 sourcetype=access_combined earliest=08/30/2017:00:00:00
latest=09/01/2017:00:00:00
| iplocation clientip | geostats globallimit=0 count BY City
iplocation clientip: This command is used to perform IP geolocation. It extracts location
information (such as city, country, etc.) from the IP addresses found in the "clientip" field.
geostats globallimit=0 count BY City: This command calculates geographical statistics based
on the location information extracted in the previous step. Specifically, it counts the
occurrences of events grouped by the "City" field. The globallimit=0 parameter ensures that
all results are returned, regardless of any default limits set in the Splunk configuration
index=botsv2 sourcetype=access_combined earliest=08/30/2017:00:00:00
latest=09/01/2017:00:00:00
| iplocation clientip
| rare Country | search percent < 1
1. rare Country: This command identifies rare values in the "Country" field. It counts the
occurrences of each unique country and calculates the percentage of occurrences relative to
the total. Countries with a percentage of occurrences less than 1% are considered rare.
2. search percent < 1: This filters the results to only include countries with occurrence
percentages less than 1%. These are the rare countries identified in the access logs within the
specified time range.
40
5. first Time Login of a User on a Machine
First Time Logins of User Accounts:
index=botsv2 sourcetype=wineventlog OR sourcetype=xmlwineventlog signature_id=4624
NOT user="ANONYMOUS LOGON" earliest=08/01/2017:00:00:00 latest=08/25/2017:00:00:00
| stats earliest(_time) AS earliest latest(_time) AS latest BY user, dest
| eval deadline = strptime("08/25/2017:00:00:00", "%m/%d/%Y:%H:%M:%S")
| where earliest >= relative_time(deadline,"-1d@d")
| convert ctime(earliest) AS earliest
| table user, dest, earliest
stats earliest(_time) AS earliest latest(_time) AS latest BY user, dest: Groups the events by the
"user" and "dest" fields and calculates the earliest and latest timestamps for each group
eval deadline = strptime("08/25/2017:00:00:00", "%m/%d/%Y:%H:%M:%S"): Converts the deadline
date string "08/25/2017:00:00:00" into an epoch time format using the strptime function.
where earliest >= relative_time(deadline,"-1d@d"): Filters the results to only include events where
the earliest timestamp is greater than or equal to one day before the deadline specified (i.e., August
24, 2017).
convert ctime(earliest) AS earliest: Converts the earliest timestamp back to human-readable format
using the convert and ctime functions.
By using this query we see in the above image two users loged in different destination , so this is look
a suspicious events
41
6. Identifying Password Guessing Attempts with Failed and Successful Logins
Failed and Successful Login Attempts:
index=botsv2 sourcetype=wineventlog signature_id IN (4624, 4625) NOT user="*$" earliest=1
| streamstats time_window=1h count(eval(signature_id=4625)) AS failed_count
count(eval(signature_id=4624)) AS success_count BY user, dest
| table _time, failed_count, success_count, user, dest
signature_id IN (4624, 4625): Filters events to include those with either signature ID 4624 or 4625.
Signature ID 4624 typically corresponds to successful logon events, while 4625 corresponds to failed
logon events.
NOT user="*$": Excludes logon events where the user ends with a "$". These events typically
represent computer account logons, which might not be relevant for user-based analysis.
streamstats time_window=1h count(eval(signature_id=4625)) AS failed_count
count(eval(signature_id=4624)) AS success_count BY user, dest: This command calculates statistics
over a streaming window of 1 hour. It counts the occurrences of signature IDs 4625 (failed logon
attempts) and 4624 (successful logon attempts) for each user and destination combination.
this query aims to provide insights into user logon activities by counting the number of successful and
failed logon attempts over time, grouped by user and destination. However, it's worth noting that the
earliest=1 parameter seems incomplete and may need to be adjusted to specify a valid time range for
the search.
42
index=botsv2 sourcetype=wineventlog signature_id IN (4624, 4625) NOT user="*$" earliest=1
| streamstats time_window=1h count(eval(signature_id=4625)) AS failed_count
count(eval(signature_id=4624)) AS success_count BY user, dest
| where failed_count > 2 AND success_count > 0
| stats max(failed_count) AS max_failed_count BY user, dest
where failed_count > 2 AND success_count > 0: Filters the results to only include combinations
where there are more than 2 failed logon attempts (failed_count > 2) and at least 1 successful logon
attempt (success_count > 0).
stats max(failed_count) AS max_failed_count BY user, dest: Aggregates the results to show the
maximum number of failed logon attempts (max_failed_count) for each user and destination
combination
this query aims to identify instances where there have been multiple failed logon attempts followed
by at least one successful logon attempt for each user and destination combination. This information
can be valuable for detecting potential security breaches or suspicious activities related to user logon
attempts.
43
7. Identifying High Network Bandwidth Consumption from a Baseline
High Network Bandwidth Consumption:
index=botsv2 sourcetype=pan:traffic earliest=1
| bin span=1d _time
| stats sum(bytes_out) AS bytes_out BY _time, src_ip, dest_ip
| eventstats avg(bytes_out) AS avg, stdev(bytes_out) AS stdev
| eval upper_bound = avg + 2 * stdev
| where bytes_out > upper_bound
| eval mbytes_out = bytes_out/1024/1024, upper_bound_mbytes =
upper_bound/1024/1024
| fields _time, src_ip, dest_ip, mbytes_out, upper_bound_mbytes
| search NOT dest_ip IN ("52.40.10.231","23.218.119.50")
| bin span=1d _time: Bins the timestamps into daily intervals using a span of 1 day. This allows for
aggregation of data on a daily basis
| eventstats avg(bytes_out) AS avg, stdev(bytes_out) AS stdev: Computes the average and standard
deviation of outbound bytes across all events.
| eval upper_bound = avg + 2 * stdev: Calculates an upper bound for outbound bytes based on the
average plus two times the standard deviation. This is a common statistical approach to identify
outliers.
| where bytes_out > upper_bound: Filters the data to include only events where the outbound bytes
exceed the calculated upper bound. This helps to identify unusually large traffic volumes.
this query aims to identify unusually high outbound traffic volumes from different source IP addresses
to various destination IP addresses, potentially indicating anomalous or suspicious network activity.
44