I just noticed my snort rules fired today on this, on a brand new ossim server I was testing. "shellcode x86 inc ebx noo" on with the source ip from Canada. Why might a brand new server, behind a firewall and a NAT router, see an alert like this coming from an external IP?
For sake of argument, let's assume you're referring to the rule mentioned by Mark in his comment. This works out well since when doing a full text search of your quoted text across all VRT and ET rules, it's the only one I found as well. It is sid 1390, found in the file
shellcode,rules for those keeping track at home.
The full rule text is:
alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"SHELLCODE x86 inc ebx NOOP"; content:"CCCCCCCCCCCCCCCCCCCCCCCC"; classtype:shellcode-detect; sid:1390; rev:9;)
Thankfully, this is a nice and simple rule. For the same of analysis let's also assume that this device is on your border and the IP variables have been properly configured.
So, this rule gets checked against every IP packet that comes into your organization. Already it seems pretty noisy. It looks in the payload section of the packet for the a string containing 25 consecutive 'C' characters. The reason for this is that this character maps to the
inc ebx instruction for the x86 architecture (as implied by the name of the rule). In the x86 architecture this instruction is functionally equivalent to NOP, and as such can be used as part of a NOOP slide, but is slightly less obvious.
This specific rule, and many of the shellcode rules in fact, are well known generators of false positives since they can often be generated by downloading binary files. The traditional tuning advice is to disable these rules on web ports.
So, depending on your risk threshold, you can either
- Disable the rules entirely
- Modify the rule to ignore packets on "web ports"
Disabling the rules is easy, and something you should be well acquainted with if you're attempting to make reasonable use of an IDS at all. Modification can be a little trickier.
Tuning By Port Filtering
Depending on your version of Snort, you should already have two variables set in your
snort.conf that will be useful. One is
HTTP_PORTS and the other is
SHELLCODE_PORTS. By default, they're set to rather basic values.
# Ports you run web servers on portvar HTTP_PORTS [80,8080] # Ports you want to look for SHELLCODE on. portvar SHELLCODE_PORTS !80
What I would recommend is changing
HTTP_PORTS to whatever you actually use in your environment, and then setting
SHELLCODE_PORTS to the inverse of that, so something like:
# Ports you run web servers on portvar HTTP_PORTS [80,8080] # Ports you want to look for SHELLCODE on. portvar SHELLCODE_PORTS !$HTTP_PORTS
Then you can modify the Snort signature to use the appropriate port variable.
alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any (msg:"SHELLCODE x86 inc ebx NOOP"; content:"CCCCCCCCCCCCCCCCCCCCCCCC"; classtype:shellcode-detect; sid:1390; rev:9;)
So now this will exclude any data coming from an external web server, so say downloading an executable from a vendor website. It is best to keep in mind that since this rule is not stateful, a malicious attacker could craft their exploit in such a way as to avoid the rule.
Tuning By State Tracking
Alternatively, we could tighten up the rule by forcing it to be stateful instead. Let's remove the port restriction and tighten up the rule to only to outside initiated communication by adding the flow keyword, turning that rule into:
alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"SHELLCODE x86 inc ebx NOOP"; flow:to_server,established; content:"CCCCCCCCCCCCCCCCCCCCCCCC"; classtype:shellcode-detect; sid:1390; rev:9;)
So now the rule will look for at least 25 consecutive 'C' characters on any outside initiated communication. So while we'll now see the cases where the malicious user spoofs their source ports, in an effort to bypass firewall restrictions, we will miss cases where the exploit code is downloaded from a local host.
In both cases, there are obvious ways to bypass the detection routine, so which direction you choose depends entirely on your risk profile and your threshold for acceptance.