Snort’s Reputation Preprocessor

Snort’s reputation preprocessor is not something new; in fact, it appeared in August 2011 in version 2.9.1. Up to that moment, the only way to manage blacklists was to create a rule with the list of IP addresses blacklisted, such as BotCC rules (emerging-botcc.rules).

alert tcp $HOME_NET any -> [,,,,,,,,,,,,,,,,] any (msg:"ET CNC Shadowserver Reported CnC Server TCP (group 1)"; flags:S; 
reference:url,; reference:url,; 
threshold: type limit, track by_src, seconds 3600, count 1; classtype:trojan-activity; 
flowbits:set,ET.Evil; flowbits:set,ET.BotccIP; sid:2404000; rev:3259;)

However, this method has a length restriction and you end up with tens of backlisted IP rules with names such as “ET CNC Shadowserver Reported CnC Server UDP (group 49)” or “ET COMPROMISED Known Compromised or Hostile Host Traffic UDP (group 43)”.

However, that’s not the main problem of this method: the main issue is performance. Taking into account that they are detection rules, packet processing is much more expensive and global performance worsens. When packet throughput is very high and there are many blacklist entries such as Shadowserver,, Malwaredomains… and our own lists, Snort performance becomes a problem and it is necessary to find a better way to manage blacklists. Then it’s time to use this preprocessor.

The first thing to do is to get a list of IP addresses from the various existing sources ( in this example) and to copy them in $SNORT_PATH/etc/reputation/ folder.

$ wget -O spyeeye.blf
$ wget -O zeus.blf
$ mv spyeye.blf zeus.blf $SNORT_PATH/etc/reputation/

Then we configure the preprocessor:

$BLACK_LIST_PATH $SNORT_PATH/etc/reputation/
# Reputation preprocessor. For more information see README.reputation
preprocessor reputation: \
   memcap 500, \
   priority whitelist, \
   nested_ip inner, \
   blacklist $RULES/compromised-ips.txt, \
   blacklist $RULES/rbn-ips.txt, \
   blacklist $BLACK_LIST_PATH/spyeye.blf, \
   blacklist $BLACK_LIST_PATH/zeus.blf

This preprocessor will alert for each packet sent to or coming from an IP address included in those blacklists. The message shown will be the one specified in file file for the preprocessor number 136:

136 || 1 || reputation: Packet is blacklisted
136 || 2 || reputation: Packet is whitelisted

If we want to change the message or modify some conditions of the rule we can do it using the preprocessor rules, in preprocessor.rules:

alert ( msg: "reputation: Packet is blacklisted"; sid: 1; gid: 136; rev: 1; \
        metadata: rule-type decode ; classtype:bad-unknown;)

Or to set limits in threshold.conf:

event_filter \
        gen_id 136, sig_id 1, \
        type limit, track by_src,  \
        count 1, seconds 3600

In my opinion, this method has a disadvantage that Sourcefire (now Cisco) should have in mind: the alert does not provide the list where is the IP that matched. This information could be very useful when we are tracking botnets, because the alert message is too generic and provides little information. Thus, it would be desirable to have the name of the matching list in the alert message and so, in our example, to know if it comes from Zeus or SpyEye botnet. We move from an scenario with have many repeated alerts that are differentiated by the suffix of the group, to an scenario with a unique single alert. If this is not a problem, you’ll get a significant improvement in performance.


  1. Excellent way of describing, and pleasant paragraph to obtain facts concerning my
    presentation subject matter, which i am going to deliver in university.