If you run Apache, you may have heard about the DoS vulnerability last week. Apache suffers from a condition where an attacker can remotely cause the web server to consume huge amounts of memory. This causes the system to be unstable and eventually, maybe even crash.
The question was raised: “Can OSSEC detect this attack?” I got to thinking about this and the answer is “probably.” Since OSSEC is primarily a log-based HIDs, we first have to look at the logs to see if there is anything juicy in there that we can use. We also need an exploit and a vulnerable system so we can reproduce the conditions of the attack. Since my server wasn’t vulnerable, FrankS in the #OSSEC channel on IRC offered to lend a hand in the rule research efforts. The first thing we noticed is several logs like this:
172.16.0.1 – - [27/Aug/2011:21:42:53 +0000] “HEAD / HTTP/1.1″ 206 354 “-” “-”
There are two things about this log that don’t quite look right: one, there are multiple HEAD requests to the root of the domain (/) and two, there are several 206 HTTP status codes. Generally, you would see 206 status codes in the context of requesting compressed content, and the request would probably be a GET. The other thing we noticed in the logs was a page allocation failure coming from Apache, like so:
Aug 27 21:59:43 hostname kernel: [ 1181.719148] apache2: page allocation failure. order:0, mode:0×20
This was promising. If we could simply look for multiple HEAD requests to / with 206 status codes in a very short amount of time, followed by a ‘page allocation failure,’ it’s probably an attack. OSSEC can do that.
There’s a certain amount of art and experience which goes into writing IDS rules. The goal is to make the rule as accurate as possible: if it does not detect the attack (false-negative), you will lose faith in the IDS; on the other hand, if it detects things which aren’t really an attack (false-positive), then you will also lose faith in the IDS and miss potential attacks. Finally, it is best to avoid making the rule exploit-specific. This can result in a situation where a small change in the exploit can avoid the rule being triggered.
Knowing what we do about the logs, how can we make a rule or set of rules that will trip when the host is attacked and be somewhat accurate? Multiple HEAD requests to / are certainly suspicious, but does the attack rely on HEAD to be successful? Section 10.2.7 of the the RFC for HTTP specifically refers to GET requests, and the attack does not seem to be specific to the HTTP method, so we can’t necessarily rely on the HEAD as an indicator. Next, we see the series of 206 codes. That is also not necessarily an indicator of the attack, but it likely is something that the webmaster may want to know about. If there are several of them in a small amount of time, we can alert the analyst to the condition for further inspection. Still, we aren’t really sure if it is the Range Header DoS. In this case, we’ll need two rules. The first rule detects the 206 status code but does not send an alert, while the subordinate rule looks for 10 of them in a 5 second interval coming from the same location (agent) and from the same source IP:
<rule id=”100002″ level=”5″>
<if_sid>31108</if_sid>
<id>^206$</id>
<description>Web Server 206 Error Code</description>
</rule>
<rule id=”100003″ level=”10″ frequency=”8″ timeframe=”5″>
<if_matched_sid>100002</if_matched_sid>
<same_location />
<same_source_ip />
<description>Multiple Web Server 206 Error Codes </description>
<description>from Same Source IP</description>
<group>web_scan,recon,</group>
</rule>
At this point, the analyst will get alerted to the DoS condition, but we are not necessarily confident that it is the Range Header attack. There’s one more rule we can create that looks for the ‘page allocation failure’ occurring within five minutes of rule 100003 firing. If we see all of this, we are reasonably confident in what is going on:
<rule id=”100004″ level=”12″ timeframe=”300″>
<if_matched_sid>100003</if_matched_sid>
<if_sid>1002</if_sid>
<program_name>kernel</program_name>
<match>page allocation failure</match>
<description>Apache Range Header DoS Attack</description>
<group>attack,</group>
<info type=”cve”>2011-3192</info>
</rule>
So, what can go wrong? Lots. The system may be so unstable that it cannot send logs to the manager. The attack might be successful with fewer than ten 206 requests within five seconds. In some cases, the ‘page allocation failure’ does not appear in the logs, although the attack still might trigger rule 10003. At least this would give the analyst a chance to visually inspect the sample of logs OSSEC sends in the alert.
Are there better ways to detect this? Certainly. Mod_Security can not only detect but also prevent the attack. Tools such as Snort are better positioned than OSSEC in situations like this. Of course, OSSEC can monitor the logs of those tools, and still alert you. The point here was to demonstrate that there is an OSSEC-only way to detect attacks like this.
Do you see a problem with the rules? Can they be subverted easily? Let me know in the comments.