The Zeek signature framework gives us the ability to use more of a
traditional approach to network security detection.
We're able to create signatures within Zeek,
and whenever the matching criteria is found in a packet or data stream,
then it will generate its event.
The signature framework is what allows us to do so and is one of the
frameworks that comes standard within the Zeek environment.
This is opposed to other monitoring and detection mechanisms
within Zeek that take a different approach,
looking at things like connections and behavior and
comparing them to how they're supposed to act.
So the signature framework can be used for specific
detections that you might want to look for,
just like in traditional IDS or IPS functions.
Take this for example.
With this signature,
we're looking at just a simple detection for seeing telnet traffic.
We wouldn't want telnet in our networks,
so this could be a good use case to use.
Or we could use signature detection to track connections and traffic
going to and from our critical assets like this one.
We could use the destination subnet and the SMB protocol
as the criteria for detection as well.
We can create simple signatures or complex ones.
Let's jump into the signature framework's capabilities so we can know
what's possible using this detection technique.
This framework breaks down the signatures into two different pieces.
We have our conditions and our actions.
The conditions define the signatures and ensures that it only
applies to the traffic that matches them.
The actions are what happens if we get a signature match.
In order to dive a little deeper into these conditions and actions,
I'll need to break up the discussion into two different pieces,
signatures for network traffic detection and
signatures for file content detection.
Writing signatures for network traffic is made relatively easy,
as long as you know what you're looking for.
As mentioned in the examples earlier in this clip,
we can use the basic networking protocols and IPs to
detect specific traffic in the network.
This is done through the use of header conditions,
content conditions, context conditions, and dependency conditions.
These match the packet headers and the payloads and other
things that Zeek either has or sees.
So header conditions specifically are what they sound like.
They match the headers in the packets.
They match many of the header fields that are used the most,
so things like source and destination IPs and ports and protocols.
We can also use ranges for these as well as comma‑separated values.
Content conditions are next and use regex,
or regular expressions, as their definitions.
We can use this to look for signatures in the
payload of the traffic coming across.
So as an example,
we can match against the URIs for the HTTP requests or the CLI input of
FTP sessions, things like that. Dependency conditions are interesting.
Here, we can require a dependency on another signature to match prior to
matching the ones we're using.
We use the signature ID here to match the connection, and we
can also use the reverse signature to match on the connection
going in the opposite direction.
Finally,
the context conditions. These force other components within Zeek to decide the
match and are only evaluated if all other conditions are met.
So, for example,
we can use the same IP condition to match if the source and destination IP
address are the same or if we're seeing certain TCP states.
Now, there are two actions that we can take with
these type of network conditions.
We can either raise an event, which will come across as a
signature_match event, and a message is sent with the
payload that matched in the event.
We can also enable a protocol analyzer as an action to
perform further analysis if needed.
File conditions and actions aren't as robust, or at
least they don't have as many options.
The file‑magic condition is what we use in signature‑based file
analysis, and this condition uses regex. So regex makes this
powerful and robust, but this is the only condition available by
default for this type of signature.
And we can compare this to the payload in the network
conditions since they're similar in concept.
The difference for the file signature is that we aren't concerned with the
protocol or connection, just the data within the file.
The action available for this is to give us the MIME type for
the information and the strength of it.
If multiple file magic signatures match against the same data,
then the higher strength in the signature wins. When we're creating signatures,
there's a few important things to keep in mind. To start, since regex is
one of the components of the more complicated signatures,
we may need to learn this, or at least the basics.
Zeek follows the Flex regex syntax.
We want to make sure that the payload matching is
optimized, so Zeek ensures that UDP and ICMP flows are
matched on an individual packet basis.
The TCP connections using the header conditions are only evaluated
for the first TCP packet from the endpoint though. If this doesn't
match, then the subsequent packets won't.
And finally, each signature is reported only once per connection.
Additional matches for the same signature are ignored.
Snort is a big tool in the industry that does perform
signature‑based network detection. In older versions of Zeek,
there was a script that would convert Snort
signatures to Zeke's signature format.
This isn't really recommended, though,
as we have the signature and behavior capabilities that
Zeek provides that give us many more benefits than just the
traditional signature analysis.
The script is no longer maintained because of this.
So if you're using Zeek,
you would need to manually convert those Snort rules or create
your own script if you wanted those to be used.