One of the key challenges in an alert centric deployment of NSM (Network Security Monitoring) is to get a context around an alert. The current crop of tools allow you to click around and accomplish the task, but only with human intervention. In this quick post, we will see how you can automate Trisul to do this by machine. Of course, you need a human to write the script, but once the script is written it is let loose on the existing data stores mechanically. Over time, the scripts are refined to include other kinds of context. This represents the intellectual property of your security team.
So the problem is this :
Write a script that gives me a single PCAP containing all packets in all flows that generated a Snort or Suricata IDS alert of Priority 1 today.
In this simple example, the context of the alert is the whole flow that generated that alert.
Flow Tagging
The trick is to create a Trisul flow tagger that marks each flow with the priority of the alert. Refer to the documentation for how to create flow taggers. Once you have the flow taggers setup, each flow is marked with the text tags IDS and the priority tags sn-1, sn-2, .. (The prefix “sn-” stands for Snort but is also used for Suricata priority). Once this is done flows with alerts look like the following
Retrieving the alert context
By clicking on Alerts -> IDS you can view alerts by signature. In the screenshot below, we have about 477 Priority 1 (Red) alerts. Our challenge is to retrieve the PCAPs of entire flows that generated these 477 alerts.
The Ruby script
We use the Ruby language and the Trisul Remote Protocol for our little script. The entire script save_pcap.rb (about 80 lines mostly comments) can be found on the Trisul Scripts Github Sample page. The script is well documented but let us see the main parts.
1. Open a SSL connection to the Trisul server using a client cert
1 2 3 |
# open a connection to Trisul server from command line args # you need password of private key (hint: it is 'client' by default) connect(ARGV.shift,ARGV.shift,"Demo_Client.crt","Demo_Client.key") |
2. Retrieve all flows in past 24 hours with tag “sn-1”
1 2 3 4 5 6 |
TrisulRP::Protocol.mk_request( TRP::Message::Command::QUERY_SESSIONS_REQUEST, { :time_interval => mk_time_interval(tmarr), :resolve_keys => false, :flowtag => "sn-1" |
The TRP Command QUERY_SESSIONS_REQUEST is used to find flows by any attributes such as IP, port, subnet, tags, etc. [Documentation]
3. Use a FilteredDatagrams command to get all packets in matching flows
1 2 3 4 |
TrisulRP::Protocol.mk_request( TRP::Message::Command::FILTERED_DATAGRAMS_REQUEST, :session => TRP::FilteredDatagramRequest::BySession.new( :session_ids => sids # returned from query # |
Extend this for more context?
Everyone of the flows in the resultant PCAP file will generate a Priority 1 Alert when run through snort/suricata. <