This article will discuss a very useful but seemingly overlooked functionality of Netfilter, a firewall code widely used in Linux, that provides content matching and filtering capabilities. This feature is offered as patch to Netfilter kernel-space code (Linux kernel) and user-space code (iptables) Since version 1.2.7a, it's been made available as a separate package called patch-o-matic. Traditional network-level firewall can inspect packets based on IP addresses, ports, TCP/IP flags completely ignoring the content in the payload. Imagine, what you can do with a firewall that can inspect more than just headers but the content in payload of every packet. With that type of firewall, you can easily block malicious worms and viruses that , I believe, are still hiting your machine every minute of the day.

More interestingly, there are tools that will convert snort signatures into iptables-aware format (even with hex string support), enabling intrusion prevention at the kernel space and stopping the attacks before they occur. Having said all that, I shall show you how to put things together:

First thing you need to do is to grab all the required packages:

  1. Kernel source code which has Netfilter kernel-space code integrated and compatible with the latest Netfilter user-space code (version 2.4.18+) . The latest stable version can be downloaded at (
  2. Netfilter user-space code which is now iptables, (latest version is 1.2.8) but currently only version 1.2.7a supports hex string patch ( and the corresponding patch-o-matic package (
  3. FWSnort, a perl script that will convert most snort rules into iptables rules. Don't forget to grab a hex string support patch that adds a hex-string capability to libipt_string.c to iptables source also. All these stuff are available at (

Unpacking them in appropriate directory:

[tony@0x90 src]$ tar -jxf linux.2.4.21.tar.bz2
[tony@0x90 src]$ tar -jxf iptables-1.2.8.tar.bz2
[tony@0x90 src]$ tar -jxf patch-o-matic-20030107.tar.bz2

Apply libipt_string patch to iptables source and build iptables kernel and user spaces code:

[tony@0x90 src]$ cd iptables-1.2.7a/extensions
[tony@0x90 extensions]$ patch -p1 < libipt_string.c.patch
[tony@0x90 iptables-1.2.7a]$ make KERNEL_DIR=../linux-2.4.21
[tony@0x90 iptables-1.2.7a]$ sudo make install KERNEL_DIR=../linux-2.4.21

Next step is to apply a string match support from a patch-o-matic package. A patch-o-matic is a series of Netfilter add-ons that provides extra functionality to original Netfilter. It has a nice automated script that will allow you to choose which patches you want integrated and checks their dependencies.

You should be aware that,some patches might not work with one another, so carefully read the comments before you apply any patches. In this case, we will apply only string-match support patch:

[tony@0x90 src]$ cd patch-o-matic-20030107
[tony@0x90 patch-o-matic-20030107]$ KERNEL_DIR=../linux-2.4.21 ./runme extra

Welcome to Rusty's Patch-o-matic!

Each patch is a new feature: many have minimal impact, some do not.
Almost every one has bugs, so I don't recommend applying them all!
Testing... fuzzy.patch NOT APPLIED ( 2 missing files)
The base/fuzzy patch:
Author: Hime Aguiar e Oliveira Jr.
Status: Under development , but works .

This option adds CONFIG_IP_NF_MATCH_FUZZY,
which allows you to match packets according to a dynamic profile
implemented by means of a simple Fuzzy Logic Controller (FLC) .

Suppported options are:

--upper-limit => Desired upper bound for traffic rate

--lower-limit => Lower bound over which the FLC starts to limit traffic
Do you want to apply this patch [N/y/t/f/a/r/b/w/v/q/?] N

This patch is not of our interest, so answer no (N) to go to the next one. Keep going until you find our string-match (-m string -string) patch and answer yes (y) to apply it:

Testing... string.patch NOT APPLIED ( 2 missing files)
The extra/string patch:
Author: Emmanuel Roger
Status: Working, not with kernel 2.4.9

This patch adds CONFIG_IP_NF_MATCH_STRING which allows you to
match a string in a whole packet.

Do you want to apply this patch [N/y/t/f/a/r/b/w/v/q/?] y
Testing patch extra/string.patch...
Placed new line
Placed new entry
Placed new Makefile line
Patch extra/string.patch applied cleanly.
Applying patch extra/string.patch...
Patch extra/string.patch applied cleanly.
Placed new line
Placed new entry
Placed new Makefile line

[Press enter to continue]

Now, go back to the directory where you unpacked the kernel source and proceed with the compilation. (If you have compiled your own kernel before, you can just skip reading this section), Instructions on how to compile and customize your kernel can be read at (

[tony@0x90 linux-2.4.21]$ make mrproper && make menuconfig
[tony@0x90 linux-2.4.21]$ make menuconfig
[tony@0x90 linux-2.4.21]$ make dep && make bzImage
[tony@0x90 linux-2.4.21]$ sudo make modules && make modules_install
[tony@0x90 linux-2.4.21]$ sudo cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.21
[tony@0x90 linux-2.4.21]$ sudo mkinitrd -f -v /boot/initrd-2.4.21.img 2.4.21

Finally, we are done with building all the components, reboot the system and enjoy your new toy.

Now let's test this new functionality and use it as an active defense system:

# This rule rejects all incoming mails with a string of "Buy Now" which many people consider it #as spam

iptables -A INPUT -p tcp -dport 25 -m string --string "Buy Now" -j REJECT --reject-with tcp-reset

# Blocks superscan ping but allows other types ping

iptables -A INPUT -p icmp -icmp-type 8 -m string -string "|0000000000000000|" -j DROP

# This will reset any connection that attempts to access a shell, in which you will find in most exploit codes

iptables -A INPUT -p tcp -m string --string "/bin/sh" -j REJECT --reject-with tcp-reset

Let's see if it works, on the server side execute nc -vv -l -p 23, on the remote host execute:

telnet 23
Connected to
Escape character is '^]'.
Connection closed by foreign host.

# Thanks to hex string support, now we can easily block x86 NOOP sleds used in most buffer overflow exploits (use this with care, since it is possible that binary files transfer in e-mail may contain these strings and will get dropped!)

iptables -A INPUT -p tcp -dport 22 -m string --hex-string "|90 90 90 90 90 90|" -j DROP iptables -A INPUT -p tcp -dport 80 -m string --hex-string "|90 90 90 90 90 90|" -j DROP

You can try any buffer overflow exploits and will find that most of them get silently dropped!

Now, you begin to have some idea on how to use this new feature as a content-based firewall system either for your local host or internal network. The FWSnort script that you have downloaded in the beginning will come into play as we will use it to convert some snort signatures into iptables rules.

First unpack the source and install it:

[tony@0x90 fwsnort-0.1]$ sudo perl

Edit the configuration /etc/fwsnort/fwsnort.conf file to suit your needs and start the conversion:

[tony@0x90 fwsnort-0.1]$ sudo fwsnort -c /etc/fwsnort/fwsnort.conf --ipt-drop

A converted set of snort rules will be written to /etc/fwsnort/ in a form of a shell script. Modify it again to suit your need , and merge it with your existing firewall rule. One thing you should keep in mind when working with a large iptables rules is that, everytime you perform an APPEND or INSERT, iptables will allocate a memory and invoke this function every time , resulting in a very slow performance. Iptables has a solution to this problem by providing you scripts that will load a large rule set into the kernel very quickly or dump the current rule set from the kernel into iptables configuration file. So I suggest you first run your firewall script and then save it as iptables format using the command:

iptables-save > /etc/syconfig/iptables

Then whenever you need to reload the firewall rule-set you simply issue the command iptables-restore , and all rules will be reloaded in a much faster manner.

Up to this point, you may think that if this functionality is so powerful, why doesn't anyone use it in replacement for snort? Although, Netfilter can perform a stateful inspection of content in a packet at the network level, it still lacks advanced capabilities in handling fragmented packets, polymorphic shell codes, traffic normalization, etc. Snort, on the other hands, can perform a pattern matching using a much faster algorithm called Boyer-Moore, supports a stateful packet analysis and stream reassembly. If you are interested in using snort as defense system, there is an ongoing honeypot project ( ) that uses a modified version of snort called snort_inline and a special set of firewall rules to achieve a hybrid firewall system.

In conclusion, I would like to comment that intrusion prevention is still at its early stage and there is no out-of-the-box product that will perfectly fits your requirements. Every network has its own culture and usage behavior thus needs a distinctly unique tuning. Don't simply rely on a single tool but do correlate data from various sources and use them to understand your network and improve your security infrastructure.

Nawapong Nakjang has been working in the areas of information security, network security and cryptography for several years. His interests include intrusion detection, honeypots, incident investigation, malicious code analysis, computer forensics and penetration testing. Occasionally, he writes security-related article and answers security questions in mailing lists. He plans to pursue his second degree in Information Security and publishes more papers to the security community.