Usage
Slips can read the packets directly from the network interface of the host machine, and packets and flows from different types of files, including
Pcap files (internally using Zeek)
Packets directly from an interface (internally using Zeek)
Suricata flows (from JSON files created by Suricata, such as eve.json)
Argus flows (CSV file separated by commas or TABs)
Zeek/Bro flows from a Zeek folder with log files
Nfdump flows from a binary nfdump file
Text flows from stdin in zeek, argus or suricata form
It’s recommended to use PCAPs.
All the input flows are converted to an internal format. So once read, Slips works the same with all of them.
After Slips runs on the given traffic, the output can be analyzed with Kalipso GUI interface.
In this section, we will explain how to execute each type of file in Slips.
Either you are running Slips in docker or locally, you can run Slips using the same below commands and configurations.
Reading the input
The table below shows the different parameter Slips uses for different inputs.
File/interface | Argument | Example command |
---|---|---|
Network interface (*) | -i | ./slips.py -i en0 |
pcap | -f | ./slips.py -f test.pcap |
Argus binetflow | -f | ./slips.py -f test.binetflow |
Zeek/Bro folder/log | -f | ./slips.py -f zeek_files |
Nfdump flow | -f | ./slips.py -f test.nfdump |
Suricata flows | -f | ./slips.py -f suricata.json |
stdin | -f | ./slips.py -f zeek |
(*) To find the interface in Linux, you can use the command ifconfig
.
There is also a configuration file config/slips.yaml where the user can set up parameters for Slips execution and models separately. Configuration of the config/slips.yaml is described here.
Daemonized vs interactive mode
Slips has 2 modes, interactive and daemonized.
Daemonized : Slips runs as a daemon in the background. which means all output, logs and alerts are written in files and nothing is displayed in the terminal.
In daemonized mode : Slips runs completely in the background, The output is written to stdout
, stderr
and
logsfile
files specified in config/slips.yaml
by default, these are the paths used
stdout = /var/log/slips/slips.log stderr = /var/log/slips/error.log logsfile = /var/log/slips/slips.log
NOTE: Since /val/log/
is owned by root by default, If you want to store the logs in /var/log/slips
,
create /var/log/slips as root and slips will use it by default.
If slips can’t write there, slips will store the logs in the Slips/output/<some_dir>
dir by default.
NOTE: if -o <output_dir> is given when slips is in daemonized mode, the output log files will be stored in <output_dir>
instead of the output_dir specified in config/slips.yaml
This is not the default mode, to use it, run slips with -D
./slips.py -i wlp3s0 -D
To stop the daemon run slips with -S
, for example ./slips.py -S
Only one instance of the daemon can run at a time.
Interactive : For viewing output, logs and alerts in your terminal.
This is the default mode, It doesn’t require any flags.
Output files are stored in output/<some_dir>
dir. the output directory used will be logged to your terminal.
By default you don’t need root to run slips, but if you changed the default output directory to a dir that is owned by root, you will need to run Slips using sudo or give the current user enough permission so that slips can write to those files.
Running Several slips instances
By default, Slips will assume you are running only one instance and will use the redis port 6379 on each run.
You can run several instances of slips at the same time using the -m flag, and the output of each instance will be stored in
output/filename_timestamp/
directory.
If you want Slips to run on a certain port, you can use the -P <portnumber>
parameter to specify the
port you want Slips to use. but it will always use port 6379 db 1 for the cache db.
Each instance of Slips will connect to redis server on a randomly generated port in the range (32768 to 32850).
In macos, you will get a popup asking for permission to open and use that random port, press yes to allow it.
However, all instance share 1 cached redis database on redis://localhost:6379 DB 1, to store the IoCs taken from TI files.
Both redis servers, the main sever (DB 0) and the cache server (DB 1) are opened automatically by Slips.
When running ./kalipso.sh, you will be prompted with the following
To close all unused redis servers, run slips with --killall
You have 3 open redis servers, Choose which one to use [1,2,3 etc..]
[1] wlp3s0 - port 55879
[2] dataset/test7-malicious.pcap - port 59324
You can type 1 or 2 to view the corresponding file or interface in kalipso.
Once you’re done, you can run slips with --killall
to close all the redis servers using the following command
./slips.py --killall
NOTICE: if you run more than one instance of Slips on the same file or the same interface,
Slips will generate a new directory with the name of the file and the new timestamp inside the output/
dir
Closing redis servers
Slips uses a random unused port in the range in the range (32768 to 32850).
When running slips, it will warn you if you have more than 1 redis serve open using the following msg
[Main] Warning: You have 2 redis servers running. Run Slips with --killall to stop them.
you can use the -k flag to kill 1 open redis server, or all of them using the following command
./slips.py -k
You will be prompted with the following options
Choose which one to kill [0,1,2 etc..]
[0] Close all servers
[1] dataset/sample_zeek_files - port 32768
[2] dataset/sample_zeek_files - port 32769
[3] dataset/sample_zeek_files - port 32770
you can select the number you want to kill or 0 to close all the servers.
Note that if all ports from (32768 to 32850) are unavailable, slips won’t be able to start, and you will be asked to close all all of them using the following warning
All ports from 32768 to 32769 are used. Unable to start slips.
Press Enter to close all ports.
You can press enter to close all ports, then start slips again.
Growing zeek directories
Due to issues running Slips on an interface on MacOS, we added the option -g
to run slips on a growing zeek directory
so you can run slips in docker, mount a
bro -C -i <interface> tcp_inactivity_timeout=60mins tcp_attempt_delay=1min <path_to>/slips/zeek-scripts
Then start slips on your zeek dir using -f normally, and mark the given dir as growing using -g
./slips.py -e 1 -f zeek_dir/ -g
By using the -g parameter, slips will treat your given zeek directory as growing (the same way we treat zeek directories generated by using slips with -i) and will not stop when there are no flows for a while.
Reading the output
The output process collects output from the modules and handles the display of information on screen. Currently, Slips’ analysis and detected malicious behaviour can be analyzed as following:
Kalipso - Node.JS based graphical user interface in the terminal. Kalipso displays Slips detection and analysis in colorful table and graphs, highlighting important detections. See section Kalipso for more explanation.
alerts.json and alerts.txt in the output folder - collects all evidences and detections generated by Slips in a .txt and .json formats.
log files in a folder current-date-time - separates the traffic into files according to a profile and timewindow and summarize the traffic according to each profile and timewindow.
Web interface - Node.JS browser based GUI for vewing slips detections, Incoming and ongoing traffic and an organized timeline of flows.
There are two options how to run Kalipso Locally:
Kalipso
You can run Kalipso as a shell script in another terminal using the command:
./kalipso.sh
In docker, you can open a new terminal inside the slips container and execute ./kalipso.sh
To open a new terminal inside Slips container first run Slips in one terminal
Now in a new local terminal get the Slips container ID:
docker ps
Create another terminal of the Slips container using
docker exec -it <container_id> bash
Now you can run
./kalipso.sh
and choose the port Slips started on. Slips uses port 6379 by default.
On the right column, you can see a list of all the IPs seen in your traffic.
The traffic of IP is splitted into time windows. each time window is 1h long of traffic.
You can press Enter of any of them to view the list of flows in the timewindow.

You can switch to the flows view in kalipso by pressing TAB, now you can scroll on flows using arrows
On the very top you can see the ASN, the GEO location, and the virustotal score of each IP if available
Check how to setup virustotal in Slips here.
The Web Interface
You can use Slips’ web interface by running slips with -w
or running:
./webinteface.sh
Then navigate to http://localhost:55000/
from your browser.

Just like kalipso, On the right column, you can see a list of all the IPs seen in your traffic.
The traffic of IP is splitted into time windows. each time window is 1h long of traffic.
IPs and timewindows that are marked in red are considered malicious in Slips.
You can view the traffic of each time window by clicking on it
The timeline button shows the zeek logs formatted into a human readable format by Slips’ timeline module
The flows button shows the raw flows as seen in the input file, of by zeek in case of running Slips on a PCAP or on you rinterface
The outgoing button shows flow sent from this IP/profile to other IPs only. it doesn’t show traffic sent to the profile.
The incoming button shows flow sent to this IP/profile to other IPs only. It doesn’t show traffic sent from the profile.
The Alerts button shows the alerts Slips saw for this IP, each alert is a bunch of evidence that the given profile is malicious. Slips decides to block the IP if an alert is generated for it (if running with -p). Clicking on each alert expands the evidence that resulted in the alert.
The Evidence button shows all the evidence of the timewindow whether they were part of an alert or not.
If you’re running slips in docker you will need to add one of the following parameters to docker to be able to use the web interface:
Use the host network by adding --net=host
, for example:
docker run -it --rm --net=host --cap-add=NET_ADMIN --name slips stratosphereips/slips:latest
Use port mapping to access the container’s port to the host’s port by adding -p 55000:55000
, for example:
docker run -it --rm -p 55000:55000 --name slips stratosphereips/slips:latest
Saving the database
Slips uses redis to store analysis information. you can save your analysis for later use by running slips with -s
,
For example:
sudo ./slips.py -f dataset/test7-malicious.pcap -s
Your .rdb saved database will be stored in the default output dir.
Note: If you try to save the same file twice using -s
the old backup will be overwritten.
You can load it again using -d
, For example:
sudo ./slips.py -d redis_backups/hide-and-seek-short.rdb
And then use ./kalipso
or ./webinterface.sh
and select the entry on port 32850 to view the loaded database.
Note: saving and loading the database requires root privileges and is only supported in linux.
This feature isn’t supported in docker due to problems with redis in docker.
DISCLAIMER: When saving the database you will see the following warning
stop-writes-on-bgsave-error is set to no, information may be lost in the redis backup file
This configuration is set by slips so that redis will continue working even if redis can’t write to dump.rdb.
Your information will be lost only if you’re out of space and redis can’t write to dump.rdb or if you don’t have permissions to write to /var/lib/redis/dump.rdb, otherwise you’re fine and the saved database will contain all analyzed flows.
Whitelisting
Slips allows you to whitelist some pieces of data in order to avoid its processing. In particular, you can whitelist an IP address, a domain, a MAC address or a complete organization. You can choose to whitelist what is going to them, what is coming from them, or both directions. You can also choose to whitelist the flows, so they are not processed, or alerts, so you see the flows but don’t receive alerts on them. The idea of whitelisting is to avoid processing any communication to or from these iocs, not to avoid any packet that contains that ioc. For example, if you whitelist the flow of the domain slack.com, then a DNS request to the DNS server 1.2.3.4 asking for slack.com will still be shown.
This whitelist can be enabled or disabled by changing the enable_local_whitelist
key in config/slips.yaml
.
The attacker and victim of every evidence are checked against the whitelist. In addition to all the related IPs, DNS resolutions, SNI, and CNAMEs of the attacker and teh victim. If any of them are whitelisted, the flow/evidence is discarded.
Flows Whitelist
If you whitelist an IP address, Slips will check all flows and see if you are whitelisting to them or from them.
If you whitelist a domain, Slips will check:
Domains in HTTP Host header
Domains in the SNI field of TLS flows
All the Domains in the DNS resolution of IPs (there can be many) (be careful that the resolution takes time, which means that some flows may not be whitelisted because Slips doesn’t know they belong to a domain).
Domains in the CN of the certificates in TLS
If you whitelist an organization, then:
Every IP is checked against all the known IP ranges of that organization
Every domain (SNI/HTTP Host/IP Resolution/TLS CN certs) is checked against all the known domains of that organization
ASNs of every IP are verified against the known ASN of that organization
If you whitelist a MAC address, then:
The source and destination MAC addresses of all flows are checked against the whitelisted mac address.
Alerts Whitelist
If you whitelist some piece of data not to generate alerts, the process is the following:
If you whitelisted an IP
We check if the source or destination IP of the flow that generated that alert is whitelisted.
We check if the content of the alert is related to the IP that is whitelisted.
If you whitelisted a domain
We check if any domain in alerts related to DNS/HTTP Host/SNI is whitelisted.
We check also if any domain in the traffic is a subdomain of your whitelisted domain. So if you whitelist ‘test.com’, we also match ‘one.test.com’
If you whitelisted an organization
We check that the ASN of the IP in the alert belongs to that organization.
We check that the range of the IP in the alert belongs to that organization.
If you whitelist a MAC address, then:
The source and destination MAC addresses of all flows are checked against the whitelisted mac address.
Tranco whitelist
In order to reduce the number of false positive alerts, Slips uses Tranco whitelist which contains a research-oriented top sites ranking hardened against manipulation here https://tranco-list.eu/
Slips download the top 10k domains from this list and by default and whitelists all evidence and alerts from and to these domains. Slips still shows the flows to and from these IoC.
The tranco list is updated daily by default in Slips, but you can change how often to update it using the
online_whitelist_update_period
key in config/slips.yaml.
Tranco whitelist can be enabled or disabled by changing the enable_online_whitelist
key in config/slips.yaml
.
Whitelisting Example
You can modify the file config/whitelist.conf
file with this content:
"IoCType","IoCValue","Direction","IgnoreType"
ip,1.2.3.4,both,alerts
domain,google.com,src,flows
domain,apple.com,both,both
ip,94.23.253.72,both,alerts
ip,91.121.83.118,both,alerts
mac,b1:b1:b1:c1:c2:c3,both,alerts
organization,microsoft,both,both
organization,facebook,both,both
organization,google,both,both
organization,apple,both,both
organization,twitter,both,both
The values for each column are the following:
Column IoCType
- Supported IoCTypes: ip, domain, organization, mac
Column IoCValue
- Supported organizations: google, microsoft, apple, facebook, twitter.
Column Direction
- Direction: src, dst or both
- Src: Check if the IoCValue is the source
- Dst: Check if the IoCValue is the destination
- Both: Check if the IoCValue is the source or destination
Column IgnoreType
- IgnoreType: alerts or flows or both
- Ignore alerts: slips reads all the flows, but it just ignores alerting if there is a match.
- Ignore flows: the flow will be completely discarded.
Removing values from the Whitelist
Whitelisted IoCs can be updated:
When you re-start Slips
On the fly while running Slips
If you’re updating the whitelist while Slips is running, be careful to use ; to comment out the lines you want to remove from the db
for example, if you have the following line in whitelist.conf
:
organization,google,both,alerts
To be able to remove this whitelist entry while Slips is running, simply change it to
# organization,google,both,alerts
Comments starting with ;
are not removed from the database and are treated as user comments.
Comments starting with #
will cause Slips to attempt to remove that entry from the database.
Popup notifications
Slips Support displaying popup notifications whenever there’s an alert.
This feature is disabled by default. You can enable it by changing popup_alerts
to yes
in config/slips.yaml
This feature is supported in Linux and it requires root privileges.
This feature is supported in MaOS without root privileges.
This feature is not supported in Docker
Slips permissions
Slips doesn’t need root permissions unless you
use the blocking module ( with -p )
use slips notifications
are saving the database ( with -d )
If you can’t listen to an interface without sudo, you can run the following command to let any user use zeek to listen to an interface not just root.
sudo setcap cap_net_raw,cap_net_admin=eip /<path-to-zeek-bin/zeek
Even when Slips is run using sudo, it drops root privileges in modules that don’t need them.
Modifying the configuration file
Slips has a config/slips.yaml
the contains user configurations for different modules and general execution. Below are some of Slips features that can be modifie with respect to the user preferences.
Generic configuration
Time window width.
Each IP address that appears in the network traffic of the input is represented as a profile in Slips. Each profile is divided into time windows. Each time window is 1 hour long by default, and it gathers the network traffic and its behaviour for the period of 1 hour. The duration of the timewindow can be changed in the the config/slips.yaml using
time_window_width
Analysis Direction
analysis_direction
can either be out
or all
The analysis_direction
parameter controls which traffic flows are processed and analyzed by SLIPS. It determines whether SLIPS should focus on outbound traffic (potential data exfiltration), inbound traffic (incoming attacks), or analyze traffic in both directions.
In all
mode, SLIPS creates profiles for both internal (A) and external (B) IP addresses, and analyzes traffic in both directions (inbound and outbound).
In out
mode, SLIPS still creates profiles for internal (A) and external (B) IP addresses, but only analyzes the outgoing traffic from the internal (A) profiles to external (B) destinations.
This parameter allows you to tailor SLIPS’s analysis focus based on your specific monitoring requirements, such as detecting potential data exfiltration attempts (out
mode) or performing comprehensive network monitoring in both directions (all
mode).

Disabling a module
You can disable modules easily by appending the module name to the disable
list.
The module name to disable should be the same as the name of it’s directory name inside modules/ directory
ML Detection
The mode=train
should be used to tell the MLdetection1 module that the flows received are all for training.
The mode=test
should be used after training the models, to test unknown data.
You should have trained at least once with ‘Normal’ data and once with ‘Malicious’ data in order for the test to work.
Blocking
This module is enabled only using the -p
parameter and needs an interface to run.
Usage example:
sudo ./slips.py -i wlp3s0 -p
Slips needs to be run as root so it can execute iptables commands.
In Docker, since there’s no root, the environment variable IS_IN_A_DOCKER_CONTAINER
should be set to True
to use ‘sudo’ properly.
If you use the latest Dockerfile, it will be set by default. If not, you can set it manually by running this command in the docker container
export IS_IN_A_DOCKER_CONTAINER=True
VirusTotal
In order for virustotal module to work, you need to add your VirusTotal API key to the file
config/vt_api_key
.
You can specify the path to the file with VirusTotal API key in the api_key_file
variable.
The file should contain the key at the start of the first line, and nothing more.
If no key is found, virustotal module will not start.
Exporting Alerts
Slips can export alerts to different systems.
Refer to the exporting section of the docs for detailed instructions on how to export.
Logging
To enable the creation of log files, there are two options:
Running Slips with
verbose
anddebug
flagsUsing errors.log and running.log
Zeek log files
You can enable or disable deleting zeek log files after stopping slips by setting delete_zeek_files
to yes or no.
DISCLAIMER: zeek generates log files that grow every second until they reach GBs, to save disk space, Slips deletes all zeek log files after 1 day when running on an interface. this is called zeek rotation and is enabled by default.
You can disable rotation by setting rotation
to no
in config/slips.yaml
Check rotation section for more info
But you can also enable storing a copy of zeek log files in the output
directory after the analysis is done by setting store_a_copy_of_zeek_files
to yes,
or while zeek is stil generating log files by setting store_zeek_files_in_the_output_dir
to yes.
this option stores a copy of the zeek files present in zeek_files/
the moment slips stops.
so this doesn’t include deleted zeek logs.
Once slips is done, you will find a copy of your zeek files in <output_dir>/zeek_files/
DISCLAIMER: Once slips knows you do not want a copy of zeek log files after slips is done by enabling
delete_zeek_files
and disabling store_a_copy_of_zeek_files
parameters,
it deletes large log files periodically (like arp.log).
Rotation of zeek logs
Rotation is done in zeek files to avoid growing zeek log files and save disk space.
Rotating is only enabled when running on an interface.
By default, Slips rotates zeek files every 1 day. this can be changed in config/slips.yaml
by changing the value of rotation_period
rotation_period
value can be written as a numeric constant followed by a time unit where
the time unit is one of usec, msec, sec, min, hr, or day which respectively
represent microseconds, milliseconds, seconds, minutes, hours, and days.
Whitespace between the numeric constant and time unit is optional. Appending the letter s to the
time unit in order to pluralize it is also optional.
Check Zeek rotation interval for more details
Slips has an option to not delete the rotated zeek files immediately by setting the
keep_rotated_files_for
parameter.
This is equivalent to telling slips, Delete all logs that happened before the last keep_rotated_files_for
days.
keep_rotated_files_for
value supports days only.
Running Slips with verbose and debug flags
We use two variables for logging, verbose
and debug
, they both range from 0 to 3.
Default value for debug is 0. so no errors are printed by default.
Default value for verbose is 1. so basic operations and proof of work are printed by default.
To change them, We use -v
for verbosity and -e
for debugging
For example:
./slips.py -c config/slips.yaml -v 2 -e 1 -f zeek_dir
Verbosity is about less or more information on the normal work of slips.
For example: “Done writing logs to file x.”
Debug is only about errors.
For example: “Error reading threat intelligence file, line 4, column 2”
To more verbosity level, the more detailed info is printed.
The more debug level, the more errors are logged.
Below is a table showing each level of both.
Verbosity | Debugging | |
0 | Don't print | Don't print |
1 | Show basic operation, proof of work | Print exceptions |
2 | Log I/O operations and filenames | Unsupported and unhandled types (cases that may cause errors) |
3 | Log database/profile/timewindow changes | Red warnings that need examination - developer warnings |
Using errors.log and running.log
Slips also logs all errors to output/errors.log (interactive mode), and /var/log/slips/error.log (daemonized mode) whether you’re using -e or not. See Daemonized vs interactive for more information about the 2 modes
General slips logs are created in /var/log/slips/running.log in case of daemonized mode and …#TODO in case of interactive mode
Reading Input from stdin
Slips supports reading input flows in text format from stdin in interactive mode.
Supported flow from stdin are zeek conn.log files (json form), suricata and argus.
For example, you can run slips using:
./slips.py -f zeek
or
./slips.py -f suricata
and you once you see the following line:
[InputProcess] Receiving flows from stdin.
you can start giving slips flows in you desired format.
All zeek lines taken from stdin should be in json form and are treated as conn.log lines.
This feature is specifically designed to allow slips to interact with network simulators and scripts.
Plug in a zeek script
Slips supports automatically running a custom zeek script by adding it to zeek-scripts
dir and adding the file
name in zeek-scripts/__load__.zeek
.
For example, if you want to add a zeek script called arp.zeek
you should add it to __load__.zeek
like this:
@load ./arp.zeek
Zeek output is suppressed by default, so if your script has errors, Slips will fail silently.
Exporting strato letters
Exporting the strato letters can be done by enabling the export_strato_letters
option in
config/slips.yaml
. once enabled, Slips will export the strato letters to strato_letters.tsv
in the output directory.
this file can be used for training Slips RNN module.
Slips parameters
-c
or--config
Used for changing then path to the Slips config file. default is config/slips.yaml-v
or--verbose
Verbosity level. This logs more info about Slips.-e
or--debug
Debugging level. This shows more detailed errors.-f
or--filepath
Read and automatically recognize a Zeek dir, a Zeek conn.log file, a Suricata JSON file, Argus, PCAP.-i
or--interface
Read packets from an interface.-l
or--createlogfiles
Create log files with all the traffic info and detections.-F
or--pcapfilter
Packet filter for Zeek. BPF style.-cc
or--clearcache
Clear the cache database.-p
or--blocking
Allow Slips to block malicious IPs. Requires root access. Supported only on Linux.-cb
or--clearblocking
Flush and delete slipsBlocking iptables chain-o
or--output
Store alerts.json and alerts.txt in the given folder.-s
or--save
Save the analysed file db to disk.-d
or--db
Read an analysed file (rdb) from disk.-D
or--daemon
Run slips in daemon mode-S
or--stopdaemon
Stop slips daemon-k
or--killall
Kill all unused redis servers-m
or--multiinstance
Run multiple instances of slips, don’t overwrite the old one-P
or--port
The redis-server port to use-g
or--growing
Treat the given zeek directory as growing. eg. zeek dirs generated when running onan interface-w
or--webinterface
Start Slips web interface automatically-V
or--version
Used for checking your running Slips version flags.-im
or--input-module
Used for reading flows from a module other than input process.
Limiting Slips resource consumption
When given a very a large pcap, slips may use more memory/CPU than it should. to fix that you can reduce the niceness of Slips by running:
renice -n 6 -p <Slips-PID>
Running Slips from python
You can run Slips from python using the following script
import subprocess
command = './slips.py -f dataset/test3-mixed.binetflow -o /data/test'
args = command.split()
process = subprocess.run(args, stdout=subprocess.PIPE)