In this demo,
I'm going to show you some ways to hunt for data exfiltration in a dataset.
We will start by looking at some general indicators that
could lead to a finding of data theft.
Then I will show you a scenario where DNScat,
a tool that can be used to exfiltrate data over the DNS protocol,
was used to send data from inside the Globomantics
network to an external source.
That will be followed by a quick installation and configuration
of the Corelight long connections Zeek script.
We will conclude the demo with a look at the long
connections notice in the Kibana web interface.
Let's get started.
What you see on the screen is a dashboard with two panels that can help
steer your hunt activities related to data exfiltration.
On the left is the Top Talkers Outbound chart that shows us
which source hosts by IP address are talking to the most
unique external destinations.
This isn't a bulletproof indicator of data theft,
but helps with situational awareness.
Learning how chatty certain hosts are on the network goes a
long way in determining anomalous behavior.
I would certainly dive deeper into the two hosts that have a
significantly higher count of outbound connections compared
to the rest of the network.
On the right, we have Outbound Data Transfers,
or uploads by hosts on the Globomantics network.
This chart gives us the protocol distribution, and right away we
notice that SSH traffic dwarfs the other protocols.
If I hide the SSH protocol, we can see the relationship of other protocols.
Ah,
it seems we have a different host that has a
relatively high volume of HTTP traffic.
Keep in mind that this chart is showing traffic going outbound and,
generally speaking,
upload traffic should be significantly less than download
traffic from hosts on a user subnet.
There are, of course, exceptions,
but you should be aware of those in your environment
and account for them in your hunt.
In this case, the HTTP volume is benign.
However, the SSH traffic is a case of data exfiltration.
Some data is uploaded during SSH and HTTP sessions,
such as GET and POST requests or commands typed in an SSH session.
However,
you should have a look at the duration of the session
and the amount of data uploaded.
For instance,
a 5‑minute SSH session that has 50 GB of outbound
data should trigger some scrutiny.
Each environment will be different,
so having a good baseline will pay huge dividends.
You can add a lot of additional charts such as outbound
connections to nonstandard ports or even a chart that
depicts the producer‑consumer ratio.
The important thing is to have a starting point for your hunt.
I'm going to show you the aggregated upload and download values using
the Network page on the Elasticsearch security UI.
We will start by looking at all source IP addresses on the network.
A good starting point is to look for outliers in the Bytes out column,
which represents data going outbound.
Here,
we can see the 27.17 and the 27.14 hosts have a much larger
amount of data compared to the other hosts.
If I sort by Bytes in, this will tell us about the data sent to that host.
Know what normal looks like in your environment.
Large numbers isn't automatically bad,
but understanding the task and purpose of a system,
as well as comparing its historical data volume with the rest of
the network, can give your hunt valuable insight.
The other half of the equation is the destination IP addresses.
Bytes in tells us how much data this host received from inside the network.
Internal IP addresses with large data spikes could be
file server traffic or data staging.
External IP addresses could be the destination of exfiltrated data.
You would have to investigate the host for signs of compromise,
look at which personas accessed the system during the relevant times,
and learn as much as you can about the destination.
Now let's take a look at DNS exfiltration.
First, I will filter the data so we only see the DNS log entries.
Then, I want to be able to quickly see the subdomain names,
so I will add the dns.question.subdomain field as a column.
Notice the view changes.
DNS exfiltration typically uses Base32 encoded or encrypted
subdomain names in the query request.
The adversary is trying to fit as much data as possible in each query request,
so we can try to find them by searching for
subdomains that have very long lengths.
Before I can use Kibana to conduct my search,
I will need to switch from KQL to Lucene so I can use a regular expression.
If you are not familiar with regular expressions,
then definitely check out the Pluralsight library which has a
few courses that can bring you up to speed.
In my regular expression,
I tend to start with around 20‑30 characters to see what shows
up and then scale the numbers up as I hunt.
Notice that there are legitimate use cases for very long query strings.
If I increase the string length to check for 80 characters,
now we have some strange‑looking DNS queries.
Do not confuse these with domain generation algorithms,
or DGAs, which are, in simple terms, pseudo randomized domain names.
What you see on the screen was generated by the DNScat tool and allows an
attacker to execute commands on a compromised system,
then exfiltrate files, all using encrypted strings in DNS queries.
The challenging thing for defenders to deal with is the fact that this
technique uses legitimate Globomantics DNS servers.
This manual process can be automated, of course,
using Watcher with a query length check or using the
Elastic machine learning package.
I won't be covering the ML package in this course,
but I wanted you to be aware that it exists.
It's time to jump back into a Linux console and look at how
to install the Corelight Zeek script.
I'm back in a remote terminal on the master sensor as the Zeek user.
The first thing I'm going to do is to update the Zeek package database.
Then, I will install the Corelight long connection script.
It does not take very long, however,
there are some dependencies for the zkg tool that
you will need to have installed.
Once the package is installed,
we need to update the site local policy to make use
of the newly‑installed script.
We have two options, first,
we can explicitly tell Zeek to enable the long connection script,
or we can enable all scripts installed using the zkg tool.
Since we only have one package installed,
either option does not have much impact.
However,
I would recommend you stick to specifying exactly which script you want enabled.
Now that we have all of that sorted,
to check if the configuration is correct we can use the zeekctl check command,
and then run the zeekctl deploy command if there are no errors.
If we take a look at the loaded_scripts.log file,
we can see that it was successfully loaded.
That's all we need to do here. Let's go back to the Kibana web UI.
Welcome back to the Kibana UI. The dataset is filtered using the notice.log,
and I've selected the LongConnection::found note so you can see
what to expect when this script is installed.
If I expand one of the events,
we can see that the script detected this particular connection as
active beyond the default 60‑minute inactivity timeout.
Without this script, this connection would have been two long connections,
one at the timeout of 60 minutes,
and the second at 48 minutes up to another hour.
That's all there is to it.
Remember to update the Filebeat configuration if you want to include the
conn long log file in your Elasticsearch database.