How to write Firekeeper rules

This document shows an example process of writing Firekeeper rule. See also detailed description of Firekeeper rule format.

... Investigated case - detecting cookie thefts ...

On February 2007 Michal Zalewski found a serious bug in Mozilla Firefox that allows malicious site to set cookies for different sites. Cookies are often used to store authentication credentials so overwriting them can, among other things, give an attacker access to your password protected sites. Details about this bug are explained here. Michal Zalewski has created a demo page that tests if your browser is vulnerable to this attack. To write Firekeeper rule that detects an attack, first, you have to learn some details about this attack, to find out if it is possible to create such a rule. To do it in our case, you should read detailed attack description and investigate source code of Michal Zalewski's demo site.

After investigation, you'll probably find out that exploitation of this bug is performed by JavaScript code that sets location.hostname property to some value. Code that does this can look like this:

location.hostname='\'; //from Michal Zalewski's demo
location.hostname           =                  ""  ;
or even
  ""  ;

... Selecting an action ...

First you should decide what you would like to do when Firekeeper detects site that performs this attack. You have two choices: When you create a new rule selecting an 'alert' action is a wise choice. It lets you easily test your rule and see if it detects malicious content and doesn't trigger false-positives alerts (alerts that are caused by legitimate sites that don't do anything evil). Empty rule with an 'alert' action looks like this:

... Detecting suspicious content ...

Now it's time to do the real work. You should add options to the rule to detect location.hostname alteration. To do it Firekeeper should examine HTTP response body in which JavaScript code is sent. Add an option to look for a string location.hostname in a response body:
alert(body_content:"location.hostname"; nocase;) 
'nocase' modifier indicates that pattern described by previous 'body_content' option should be searched without case distinction.

Ok. Now you can start testing the rule. Add it to one of your Firekeeper rules file or create new file as explained in the Firekeeper help. Rule should detect attacks well, the problem is that it also picks up some legitimate usage of location.hostname property. Site can not only write to this property but also read it, which isn't a suspicious behaviour. To restrict alarms to sites that are setting location.hostname property add an option to search for an expression: 'location.hostname[any number of white-space characters]='. To do it you have to use regular expressions. 'body_content' option can search only for a predetermined string, it can't search for things like 'any number of white-space characters'. You should use 'body_re' option instead:

alert(body_content:"location.hostname"; nocase; body_re:"/location\.hostname\s*=/i";)

Ok. Expression '\s*' means any number of white-space characters including 0. Modifier 'i' means that search should be case insensitive. You may wonder why 'body_content' option is left as it is now somehow redundant with 'body_re' option. If you read document about Firekeeper rule syntax carefully, you will learn that to achieve the best performance each rule should have at least one *_content option even when they are redundant with *_re options.

To try a new rule it is the best to surf with this rule enabled for a while. You should also create some test page and check if alerts are correctly triggered by suspicious content. If you surf with your new rule to some Wikipedia site you will see that the rule is triggered by JavaScript on it. This is the false positive alert. To see if you can get rid of it you should examine content of this JavaScript file. It contains instruction:
if (window.location.hostname == "localhost") {
We forgot about equality operator '==' which is picked up by the rule, but it doesn't change location.hostname property. You can simply correct it:
alert(body_content:"location.hostname"; nocase; body_re:"/location\.hostname\s*=[^=]/i";)
Now 'body_re' option is looking for location.hostname string followed by any number of white-space characters followed by a single '=' character followed by anything except '=' character. That's it, now the rule should work fine, load Michal Zalewski's demo page to see if the alert window is displayed.

... Making alerts more verbose ...

The rule works fine but the alert window displayed when it is triggered doesn't give to much useful information to the user. You should add short message that is displayed in the alert window. To do it, add an option to the rule called 'msg':
alert(body_content:"location.hostname"; nocase; body_re:"/location\.hostname\s*=[^=]/i"; msg:"location.hostname alteration attempt";)
Next, you can define links that give user some additional information about this attack. You can, for example, link to the vulnerability description on bugtraq. To do it you should find a bugtraq ID assigned to this vulnerability on security focus site (it is 22566):
alert(body_content:"location.hostname"; nocase; body_re:"/location\.hostname\s*=[^=]/i"; msg:"location.hostname alteration attempt"; reference:bugtraq,22566;)
You can add as many references as you want. Add another one to Michal Zalewski's demo site:
alert(body_content:"location.hostname"; nocase; body_re:"/location\.hostname\s*=[^=]/i"; msg:"location.hostname alteration attempt"; reference:bugtraq,22566; reference:url,;)
That's it, alerts give now much more useful information to the user, and you are ready to surf and lookup for evil pages that are trying to exploit 'location.hostname' bug :)

For questions or comments about firekeeper, please send a message to the firekeeper mailing list.
Copyright © 2006-2007 Jan Wrobel <>. All rights reserved. Privacy Policy.