Near-realtime blacklist warnings with NetFlow, Perl and OTX

Posted at 7:43 pm in Uncategorized

Installing IDS sensors in your network for monitoring traffic is not always feasible, for several possible reasons. Perhaps the network infrastructure is too complex, leading to blind spots. Maybe the affected network links have higher capacity than your ad hoc IDS sensor, causing packet loss on the sensor. Or your company may be organized in such a way that installing “foreign” hardware in the network infrastructure is not easily done.

Still, without going “all in” on a potentially expensive IDS project, it could be useful with some insight into what’s going in to and out from your network, keeping an eye on known malicious IP addresses and networks. Setting up a NetFlow feed from the company’s routers will usually not incur any significant loads, nor does it interfere with the network traffic, so that could be a possible approach. I’ve previously covered NetFlow and SiLK for rear-view mirror analysis of whether any blacklisted IP resources have been communicating with your system and users in the past. What if we could do the same, just in (almost) real-time? With the help of Perl and the Net::Flow module, we can.

Bill of material

  • Router(s) that support(s) NetFlow (I’ve used version 9 but the Perl module seems to support v5 and IPFix as well).
  • Perl, and the Net::Flow module for parsing the NetFlow data.
  • One or more IP blacklists of your choice. For the purpose of this test I’m using my subscribed lists from AlienVault’s Open Threat Exchange, but the list of IP addresses to compare against can easily be extended with – or replaced by – other lists like the SANS blocklist or any DNSBL/RBL.

The Perl script I’ve set up for this purpose is crudely derived from the Net::Flow sample code, and after my tweaks it’s currently not something that should see the light of day. Its output, however, is pretty enough for a modest presentation. The IP addresses (IPv4 as well as IPv6) and other info are extracted from the different flow fields, detailed in this Cisco document.  In my script, each offending IP is associated with URLs linking to OTX pulses where further information can be found.

Some sample entries from the Perl script’s output:

2016-06-07 12:38:20 : -> (TCP)

2016-06-07 13:37:46 : -> (TCP)

2016-06-07 13:51:34 : -> (TCP)

2016-06-07 17:51:13 : -> (TCP)

2016-06-07 18:00:52 : -> (UDP)


Some unsolicited questions and answers

  • What can this be used for? It can be a proof-of-concept, in cases where you might need to argue why you want to install an IDS. It can also be used for statistical purposes, to get a grasp of how often your network is communicating with malicious systems on the Internet.
  • Will I be missing information with this simplified setup? Yes, most likely. This implementation is not intended as an IDS replacement, but it will give an indication of unwanted activity to and from your network. Also, your router may provide sampled NetFlow data, e.g. only a portion of the traffic will be selected for NetFlow analysis. At times you might see only the response traffic, in cases where a remote node contacting a non-responsive port will not always be classified as an established flow but a related ICMP response might be.
  • Why isn’t it real-time? A flow won’t be registered by the router until a connection is completed or has timed out. Depending on your router’s configuration, it could also be batching up the NetFlow feeds for regular transfers. I’ve seen 20 to 30 seconds delay between the actual connection and the NetFlow push from the router.
  • Can I use the output somewhere else? Sure, you can make the Perl script log to syslog or to a file that OSSEC or something similar can read from.


Written by bjorn on June 7th, 2016

Tagged with , , , , , , ,