I recently had an opportunity to do some research into a large volume of Snort IDS rules that had begun to fire (to the tune of millions of alerts a day) for an organization. At first glance these alerts appeared to be false positives, but they smelled like a lazy application DDoS attempt from some external source after a little review. When the alerts didn’t stop, and considering the application in question wasn’t even being used I needed to provide clarity as to why these alerts were firing. A simple “ignore them, they’re false positives” wasn’t going to fly here.
The snort rule summary is as follows (full code displayed later):
Its an Oracle 10g application exploit alert, SID 15554
Traffic flow: to server
Packet contents match following Perl regular expression (more explanation to follow): /^(GET|POST|HEAD)s+[^x25]*x25[x23x24x27x2ax2bx2dx2ehlqjzt1234567890]*[diouxefgacspn]/i
Don’t let the regex above spook you. Even tho it has hex characters in it, breaking it down isn’t too hard. I’ll get into it’s meaning in more detail below:
First, a little background on big companies and their web sites. Oftentimes the volume of traffic to the sites is so large companies will use clustered web servers with load balancing appliances in front of them. For security reasons the server cluster won’t be hosting the website on normal port 80 or 443, but the virtual IP (VIP) of the load balancer will accept 80 and 443 traffic. Then, the traffic is NAT’d internally and distributed to one of the web servers on a non standard port. What I discover is that the company had randomly decided to use a port in the 6000-6199 range for post nat’d web traffic. That in conjunction with the IDS placement and meant the first five cases of the Snort rule were met. However, five out of six cases is not enough for an alert.
The final case to match was the regular expression. Here is an attempt to breakdown what this expression means in a more user friendly format:
Match the words “GET, POST or HEAD” if they appear at the start of a message. Then match any number of spaces but not a line that ends with a “%” sign. Continue to match any series of characters (both numbers and letters) followed by a “%” sign. Continue to match if the next set of characters matches one of these “#$’*+-. hlqjzt1234567890” and lastly match if the next characters contain one any of these “diouxefgacspn”. This is all case sensitive.
After some HTTP packet analysis it was determined that the search functionality on the website matched this regular expression, and was causing the alert to fire erroneously. Here is a sample of an HTTP GET request for a user initiated search:
GET http://www.bogusurl.com/enUS/search-results/default.html?search=test&Ep=search:results:results%20page HTTP/1.0
Other legitimate requests may also have been matching the Snort rule.
Verification of the regular expression matching was performed on the following website: http://www.internetofficer.com/seo-tool/regex-tester/
The end result was something of a perfect storm, wherein the Snort rules’ cases where being matched by legitimate web traffic. This explanation satisfied the organization and the rule was flagged as false positive.
Here is the complete text of the Snort rule:
oracle.rules:alert tcp $EXTERNAL_NET any -> $HOME_NET [6000:6199] (msg:”ORACLE Oracle Application Server 10g OPMN serviceformat string vulnerability exploit attempt”; flow:to_server,established; content:”HTTP”; nocase;
balanced-ips drop, policy security-ips drop; reference:bugtraq,34461; reference:cve,2009-0993;