GCA

Checking if an IP is part of a subnet stored in an AL

Blog Post created by GCA on Jul 11, 2014

Time has come to dig up an old post that I wrote more than 6 years ago. At that time I though this method would only be useful for a few months because I found this missing feature so useful that I was convinced it would be very quickly implemented in Arcsight. Unfortunately I was wrong and at this moment in time the only evaluation condition usable with an active list is still "equal to". While this is enough most of the time there are some situation where it is simply not sufficient.

 

Let's take the following Use Case: You are collecting a big list of suspicious subnets and you would like to create an alert when traffic related to those is detected. Because your list is big and because it is frequently updated you don't have any other choice than using an Active List to store the information. So how can we check if an IP is part of the subnet stored in an AL ? The way I do it is to modify the collected information with a script before importing it into Arcsight.

 

 

  1. I create 2 active lists, one for class C ranges (AL1), and the second one for IP addresses (AL2)
  2. Each range with a netmask < 24 is split in a list of ranges with a netmask of 24. For instance, 10.10.10.0/23 will be split in 2 subnets: 10.10.10.0/24 and 10.10.11.0/24 but I will only store the 3 first bytes of the IP. In our example 2 entries are created in AL1:  10.10.10  and 10.10.11.
  3. Each range with a netmask > 24 is split in a list of IPs stored in AL2. For instance 3.3.3.0/31 will be split in 3.3.3.0 and 3.3.3.1 and store as such in AL2.
  4. Each range with a netmask = 24 is stored in AL1 (only the 3 first bytes, ie:  1.2.3 )

 

     For instance, if the blacklist contains :

                    1.1.1.1

                    2.2.2.0/24

                    3.3.3.0/31

                    4.4.4.0/23

     AL1 (Class C subnet) will contain:

                    2.2.2

                    4.4.4

                    4.4.5

     AL2 (IP) will contain:

                    1.1.1.1

                    3.3.3.0

                    3.3.3.1

 

Now we can create 2 rules watching for the traffic.

  • The first one will check traffic coming from or going to IP listed in AL2 which is quite trivial.
  • Second rule will
    • use a variable to extract the three first octet of the source or destination IP and concatenate them with dots. For instance, an IP source being 5.5.5.5 will become 5.5.5 . The idea is to use the IP to recreate the virtual class C subnet this IP would belong to.
    • check this value with the AL1. If there is a match, this means the IP belongs to a class C subnet listed in AL1 and the rule must trigger.
  • NB : I created two rules for more clarity but you can do the same with a single rule

 

At first this process can seem to be complex but with a relatively basic script it can become very powerful and pretty easy to maintain. Your script could for instance:

  • Download the list of subnets from the Internet on a regular basis
  • Split all the subnets according to what has been explained here above.
  • Generate one CEF event per subnet and send those to a syslog connector in order to allow rules to populate the AL automatically.
  • Because this is a kind of "set it and forget it" mechanism I recommend you to add some checks in order to ensure the blacklist is properly retrieved and parsed over time (they could disappear or the format could change). If an issue happen your script should generate an error message in CEF format for easy monitoring in ESM.

 

When this is all done, you can just sit down and relax, all the work is done automatically.

 

 

Extra notes: while this should be sufficient for most of the usage, you could decide to replicate the concept for Class B subnets. For instance, you add another AL (AL3) for Class B subnets where entries only contain the 2 first bytes. Each Subnet < 16 is split in /16 subnets and /16 subnets are stored directly in AL3. For instance, 10.10.0.0/15 would be split in 10.10.0.0/16 and 10.11.0.0/16. These subnets would be stored in AL as  10.10  and 10.11.  Thanks to this mechanism it is possible to limit the number of entries in your Active Lists. Indeed you will never create more than 128 entries in an AL whatever the original subnet you collected from your original blacklist.

 

          For instance:

      • 1.2.3.0/24 --> 1 AL entry
      • 1.2.3.0/26 --> 64 AL entries
      • 1.2.0.0/16 --> 1 AL entry
      • 1.2.0.0/19 --> 32 AL entries
      • 1.2.0.0/15 --> 2 AL entries

 

This should allow keeping the number of AL entries to a reasonable number of entries even for big blacklists.

 

Enjoy

Gaetan

Outcomes