Wednesday, December 28, 2011

Cross-Platform Single-Request Web Server DoS From CCC

Security never sleeps, even if it is the week between Christmas and New Year's, and most of you are on vacation, enjoying time with your family, or just goofing off because the office is empty. Today's reminder of that reality comes from Alexander Klink and Julian Walde, who presented yesterday at the 28th Annual Chaos Communication Congress a method of consuming a web server's entire CPU with a simple, low-bandwidth POST request. In fact, according to the advisory they released after the talk, as little as 30k/sec could be necessary to occupy a single i7 core, depending on the target platform.

While the details of the attack are complex and vary from one target platform to another, the essence of it is that if you can send a large number of key/value pairs where the keys cause collisions in the receiving system's hashing algorithm, each colliding key will consume exponentially more CPU time to parse than the last. This makes for fairly straightforward detection in Snort - exceptionally large numbers of key/value pairs are necessary to trigger the bug, and so it's a matter of counting them up in a given request.

We've released SIDs 20823 and 20824 in an SEU late last night to cover this vulnerability.

For more information on this vulnerability check out the MSRC blog post here. The VRT Snort rules for detecting this vulnerability are discussed in their blog post.

We are working on the additional issues patched in MS11-100, and will provide coverage for those shortly.

Friday, November 18, 2011

Malware Mythbusting

The malware sandbox that I've previously discussed on this blog has made for a lot of useful Snort rules - but it's also helped get me some excellent speaking slots around the world this year. This time, I've just wrapped up a presentation titled "Malware Mythbusting" at Ruxcon, Australia's premier technical security conference.

The premise of the talk was simple: there's a lot of hype surrounding malware, and if you're someone tasked with keeping a network secure, there's generally not a lot of good information about the nature of the threat. Can I cut off China and Russia and make all the C&C servers go away? Are spambots really a major threat, or has garden-variety malware moved on? Are the people writing malicious software a bunch of evil geniuses, or can a little bit of diligence and attention locate heaps of nasty behavior on the network?

While I don't claim to have all the answers - no one does - I hope to have done a reasonable job of answering some of these questions during this talk. For those of you who didn't have the chance to make it down here - and for those who did that want to take a closer look at some of the data presented - I've made my slides available here. As I noted in the talk, if you have questions that it left unanswered, or if you're interested in working with us on malware research, drop the VRT a line - we're happy to collaborate with anyone who has good ideas. After all, at the end of the day, we're all on the same team here, and anything that can be done to clean more malicious software from the Internet is a good thing, regardless of the source.

Tuesday, November 8, 2011

Microsoft Security Advisory 2639658

Microsoft recently added a new initiative to its Microsoft Active Protection Program (MAPP), called the Advisory Initiative program, which gives partners up to 96 hours to provide protection for discovered vulnerabilities. Microsoft piloted the program with an advisory release on the Win32K TrueType font parsing engine, related to the Duqu malware (CVE-2011-3402). Sourcefire released its protections for this threat within the first 48 hours, as noted on the MAPP site

SID: GID 3, SID 20539

Duqu exploits a vulnerability in Windows in the way it parses TrueType fonts and it can create an open tunnel into a user's computer. Then attackers have the freedom to gain full system access and run arbitrary code and modify data, install applications, and, essentially, use the system as the user would. This flaw, for which Microsoft previously issued a workaround, is exploitable across many Windows platforms. Despite this, Microsoft reports that they are currently seeing low customer impact at this time.

More information, as well as other vendors who responded within 48 hours, can be found on the MAPP program web site.

Thursday, November 3, 2011

Android Malware Analysis: A How-To

While mobile malware comprises only a tiny fraction of the overall landscape in terms of volume, it is fast becoming essential to address from an enterprise security standpoint. Unfortunately, very few people would even have a clue where to start if charged with analyzing a program on a smart phone. This disconnect provided the rationale for a presentation I recently gave at Hack in the Box Malaysia on how to go from "I've got an Android APK file, now what?" to full static and dynamic analysis.

The slides, available here, contain links to a number of useful tools. The good news for longtime readers of this blog is that the process is even easier now than it was when Alain Zidouemba discussed reversing Android apps last August. Free software is available that can deliver the original Java source for any given Android app. My presentation also provides an overview of the Android permissions system and its relevance to static analysis, as well as some example packet captures from in-the-wild malicious apps.

One useful piece of advice remains the same since Alain's original analysis, however: the vast majority of malicious apps come not from the Google market but from third-party package distribution sources. We're not saying that you shouldn't ever pull an app from outside the market, just that you should do your homework before you do.

Wednesday, November 2, 2011

Say Hello to the file-identify category

This week we are introducing a new rule category into the VRT rule set, named "file-identify.rules". The purpose of this category is to standardize the structure of rules that “set” a flowbit and to enhance detection by looking into file data. The changes will occur in two stages.

Stage 1. The creation of a series of rules that detect the "magic" in files, probably around 70 to start, with more being added as time passes and needs arise. For example:

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any (msg:"FILE-IDENTIFY PNG file magic detection"; flow:to_client,established; file_data; content:"|89|PNG|0D 0A 1A 0A|"; within:8; fast_pattern; flowbits:set,http.png; flowbits:noalert; classtype:misc-activity; sid:20478; rev:1;)

In this example, the magic at the beginning of the file is detected (the "|89|PNG|0D 0A 1A 0A|”) and the flowbit is set for this particular file type. This will allow a flowbit to be set for file types based on the data in the file and not the file extension in say a URI. For example, if a rule looks for “.jpg” in the URI and sets the “http.jpg” flowbit to track the download for the image requested, but the file is actually a PDF with a .jpg extension, then further detection based on the setting of this flowbit could lead to false positive events at best and false negative events at worst.

Stage 2. Move all URI checks for file extensions over to "file-identify". A lot of work has been done to cleanup these rules. They now have a well defined and consistent structure, with references, flow, message, detection, classtype and pcre options all standardized.

For example:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"WEB-CLIENT .hta download attempt"; flow:to_server,established; content:".hta"; nocase; http_uri; pcre:"/\.hta(\b|$)/Ui"; flowbits:set,http.hta; flowbits:noalert; classtype:not-suspicious; sid:3551; rev:4;)

Now reads:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"FILE-IDENTIFY HTA file download request"; flow:to_server,established; content:".hta"; nocase; http_uri; fast_pattern:only; pcre:"/\x2ehta([\?\x5c\x2f]|$)/smiU"; flowbits:set,http.hta; flowbits:noalert; reference:url,; classtype:misc-activity; sid:3551; rev:5;)

And rules like this:

alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT GIF transfer"; flow:from_server,established; content:"image/"; nocase; http_header; pcre:"/^Content-Type\x3a(\s*|\s*\r?\n\s+)image\x2fgif/smiH"; flowbits:set,http.gif; flowbits:noalert; classtype:protocol-command-decode; sid:3535; rev:9;)

Have been changed (or eliminated in this case) and have been split into two:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"FILE-IDENTIFY GIF file download request"; flow:to_server,established; content:".gif"; nocase; http_uri; fast_pattern; pcre:"/\x2egif([\?\x5c\x2f]|$)/smiU"; flowbits:set,http.gif; flowbits:noalert; classtype:misc-activity; sid:17394; rev:2;)

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any (msg:"FILE-IDENTIFY GIF file magic detection"; flow:to_client,established; file_data; content:"GIF8"; within:4; fast_pattern; content:"a"; within:1; distance:1;  flowbits:set,http.gif; flowbits:noalert; classtype:misc-activity; sid:20459; rev:1;)

Over the course of the next week, these changes will be made to the rule set, and a new variable will be introduced in the snort configuration file:

portvar FILE_DATA_PORTS [$HTTP_PORTS,110,143]

Following these two introductions, the structure and formatting of all the flowbit names will be standardized. For example, replacing names like “http.gif” with “file.gif”, will reflect more accurately what is being detected.

Action items for you:

#1. You'll need to add the above variable to your snort.conf, use the snort.conf in the VRT tarball, or download the new snort.conf .
#2. If you are using the Sourcefire product, or PulledPork, the change should be minimal. The Sourcefire product and PulledPork perform flowbit auto-enabling and resolution. If you are using another tool to mange your installation, you will need to pay attention to this rule category.

Monday, October 31, 2011

SSL DoS, Snort, and You

Upon hearing of the release of THC SSL DoS tool, we decided to download it and look at it in our lab. The idea was intriguing and we were curious to see it in action.

If you are unfamiliar with the method utilized, the THC SSL DoS tool seeks to issue a Denial of Service (DoS) against hosts that offer SSL/TLS encrypted services. Unlike SSL flooding techniques of the past, this attack does not do this with rapid connections. Instead it makes a small number of connections and then rapidly renegotiates the SSL handshake inside those same connections.

The problem is that an attacker no longer needs a large amount of bandwidth or to mount a distributed attack to be able to successfully perform an SSL DoS attack. By utilizing a single SSL connection to a server, thousands of SSL handshake renegotiation requests can be performed very quickly.

To quote THC:
"Traditional DDoS attacks based on flooding are sub optimal: servers are prepared to handle large amount of traffic and clients are constantly sending requests to the server even when not under attack.

The SSL-handshake is only done at the beginning of a secure session and only if security is required. Servers are _not_ prepared to handle large amount of SSL Handshakes."
So, what can Snort do for you? We knew that with the default configuration on Snort's SSL preprocessor we were not going to see the renegotiation happening. The reason is that once a successful SSL connection is made, without an SSL decryption appliance (Sourcefire sells them), Snort will ignore the rest of the conversation - the logic being that, since it's now encrypted, we can't do any detection on the traffic anyway. However, all hope is not lost. If you are in a position in which you need to detect this, there is a way. This detection behavior is controlled by the SSL preprocessor option "noinspect_encrypted"; removing that keyword will cause Snort to continue inspection after a session goes encrypted.
So, what next? First, let's look at the SSL/TLS record layer content types:

Hex Dec Type
0x14 20 ChangeCipherSpec
0x15 21 Alert
0x16 22 Handshake
0x17 23 Application

Since the attack utilizes handshake renegotiations, we are interested in the Handshake (0x16). Now we are interested in the two bytes of SSL/TLS version information:

Major Minor Version Type
3 0 SSL 3.0
3 1 TLS 1.0
3 2 TLS 1.1
3 3 TLS 1.2

So, if we take the content type, major version, and minor version within the first three bytes, we can get a pretty decent match. Next we sprinkle in a detection_filter to track the number of renegotiations, and finally we remove the noinspect_encrypted from the SSL preprocessor, and there it is ... SSL negotiation DoS detection.

This isn't a configuration I would recommend unless you've got a good reason because there will be a performance penalty. However, if you need it, you've got it. Run the rules that match your environment, adjust the ports as needed, and tweak the detection_filter to taste. The rules will be released in the next SEU.

This blog post has been brought to you by the letters V, R, T.

alert tcp $EXTERNAL_NET any -> $HOME_NET [443,465,587,995,993] (msg:"DOS multiple SSLv3 Encrypted Handshake messages - THC-SSL tool, potential DoS"; flow:established,to_server; ssl_state:!client_hello; content:"|16 03 00|"; depth:3; detection_filter:track by_src,count 25, seconds 2; reference:url,; classtype:attempted-dos; sid:20436;)

alert tcp $EXTERNAL_NET any -> $HOME_NET [443,465,587,995,993] (msg:"DOS multiple TLSv1 Encrypted Handshake messages - THC-SSL tool, potential DoS"; flow:established,to_server; ssl_state:!client_hello; content:"|16 03 01|"; depth:3; detection_filter:track by_src,count 25, seconds 2; reference:url,; classtype:attempted-dos; sid:20437;)

alert tcp $EXTERNAL_NET any -> $HOME_NET [443,465,587,995,993] (msg:"DOS multiple TLSv1.1 Encrypted Handshake messages - THC-SSL tool, potential DoS"; flow:established,to_server; ssl_state:!client_hello; content:"|16 03 02|"; depth:3; detection_filter:track by_src,count 25, seconds 2; reference:url,; classtype:attempted-dos; sid:20438;)

alert tcp $EXTERNAL_NET any -> $HOME_NET [443,465,587,995,993] (msg:"DOS multiple TLSv1.2 Encrypted Handshake messages - THC-SSL tool, potential DoS"; flow:established,to_server; ssl_state:!client_hello; content:"|16 03 03|"; depth:3; detection_filter:track by_src,count 25, seconds 2; reference:url,; classtype:attempted-dos; sid:20439;)

Wednesday, October 26, 2011

Razorback 0.3 Released

Yesterday we released Razorback 0.3, the result of the Q3 development run.  Q3 focused on building out the scripting nugget, reworking how the Snort-as-a-Collector nugget works and building out a VM image so you can easily tryout the Razorback system.

The scripting nugget is a huge addition to Razorback.  The scripting nugget uses XML across named pipes to pass registration, alerting and logging information back to the system.  This allows the use of any scripting (or even compiled) language that can pass XML out STDOUT with Razorback.  We ship a ruby gem that makes writing detection scripts fairly straightforward as well as a sample ruby nugget.

The scripting nugget calls each script on startup with the --register argument.  This causes the scripts to output their registration information and the script nugget then registers on their behalf.  The scripting nugget then handles retrieving data blocks and calling the nuggets when they are needed for detection.  The scripting nugget then parses the alerting and logging output and uses the standard C API to alert and log on behalf of the scripts.  Finally, the scripting nugget is constantly watching the scripts directory, so adding detection to a running system is as simple as copying a new script into the directory.

There have been a couple of versions of Snort released since we initially built the SAAC and there were some lingering issues we wanted to clean up, so the Amish Hammer sat down and basically rewrote it from the ground up.  The shipping version is now based on Snort, has better memory management and is fully integrated with the current API allowing for the data block captured to have the request information attached to it.  Basically this means that for any given captured data block, we have all the information about how it was requested:  hostname, URI, IP addresses, ports etc...  Very useful for forensics work.

Finally, we have built out a FreeBSD based virtual appliance so you can easily bring up and interact with a Razorback installation.  The system comes pre-configured witha ll of the sub-components requried for Razorback to run:  memcached, MySQL and ActiveMQ.  In addition, it provides the following nuggets:  Yara, OfficeCat, ClamAV, Archive Inflate, Scripting, File Inject and a Snort-as-a-Collector nugget.  Provided you have an API key you can also enable the Virus Total nugget and if you have a license, you can activate the PDF Dissector nugget.

Beyond all this are various and sundry bug fixes, performance enhancements and usability improvments.

You can find the source code for 0.3 here:

You can find documentation on the VM here:

You can find the VM itself here:


Thursday, October 6, 2011

Fishing For Malware: Tread Softly and Carry A Big Net

If you pay attention to the list of new rules in each SEU, you've probably noticed us adding a lot of malware rules lately. While on the surface it may appear that we're just picking random samples out of the millions of different pieces of malware available on the Internet, there's actually a method to our madness that's worth explaining here, to help you make the best possible decisions on which rules you want to enable in your environment.

Outside of cases where we're asked to provide coverage for a specific piece of malware, our primary goal whenever we add a new rule is to cover more than just one sample with any given rule. After all, if there was a 1:1 ratio of rules to malware, we'd end up writing hundreds of thousands of rules and still only touching the tip of the iceberg in terms of total detection - whereas if we can write a rule that catches thousands of different pieces of malware, we can provide much more useful detection in a much more manageable way.

A good example of this principle in action is SID 20232, released in SEU 507:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"BOTNET-CNC Trojan Win32.Cycbot outbound connection"; flow:to_server,established; content:"?v"; http_uri; content:"tq=g"; distance:0; http_uri; content:"User-Agent|3A 20|mozilla/2.0|0D 0A|"; fast_pattern; http_header; pcre:"/(gif|jpg|png)\x3fv\d{1,2}\x3d\d{1,2}\x26tq\x3d/U"; metadata:policy balanced-ips drop, policy security-ips drop, service http; reference:url,; classtype:trojan-activity; sid:20232; rev:2;)

The analyst who wrote this rule was initially investigating the piece of malware named in the message string specifically, with the string "jpg?v" as a key piece of detection. However, when he began digging through our malware sandbox for samples to test his initial rule with, he realized that a very large number of samples could be detected if he were to broaden his search to look for either "jpg?v", "gif?v" or "png?v" - 3,856 in just the month of September 2011, to be specific. Since relying solely on a five-byte URL match could easily produce false positives, he analyzed several samples by hand, and was able to add the other checks in the rule to keep false positives at bay while still detecting a huge amount of malware. Amazingly enough, that rule will detect 122,630 distinct samples that have run through our sandbox since the start of 2011!

While cases like this are great from a detection perspective, they present a bit of a challenge from a metadata perspective. We can't just have a rule message like "BOTNET-CNC this rule is awesome it finds lots of malware", nor could we possibly list all the different pieces of malware this one rule catches in the message string. The same principle applies to rule references - leaving them out altogether isn't useful, and we can't add references for all the different malware the rule catches. Using data from the targeted piece of malware, or the one that the rule catches most frequently, is a compromise that gives users some idea of what the rule is doing, while still retaining sanity in terms of size.

So the question that users face is, "how do I know when a rule is really useful like this, vs. something more targeted and less broadly applicable?". The answer comes from the default policies that a rule is placed into. If a rule will catch a large amount of malware, and do so without significant false positives or performance problems, we'll place it into the balanced-ips policy. Rules that run more slowly, may generate some false positives, but will still catch more than one piece of malware at a go end up in the security-ips policy. Cases where a rule isn't broadly applicable are not placed into any of the default policies.

Of course, we've received word from multiple customers that they simply enable the entirety of the BOTNET-CNC, BACKDOOR, and BLACKLIST categories with little to no trouble, and plenty of valid detection. Your mileage may vary, of course - but if you're having problems with malware on your network, it may be worth a look. :-)

Thursday, September 29, 2011

Mac "Trojans" this past weekend. OSX.Revir-1

Over the weekend a rash of articles appeared across the Internet referring to a "new" Mac Trojan named "Revir.A". The first one that came to my attention was on the F-Secure Blog last Friday. I was able to obtain a copy of the referenced sample for this "Trojan" and started to analyse it.

However, before I tell you how it turned out, I can't tell this story without telling another story first.

As many security researchers are, I belong to several Mailing lists. They are great tools to use when exchanging information with other researchers or talking about the newest things we've found. It seems that no matter what the new technology is for exchanging data (Sharepoint, Wiki's, Google Wave), Email always seems to win.

Well, back in May I was able to mine a small nugget of awesome from one of these Mailing lists. Someone warned the list members of a new "Trojan" that was spreading, spoofing who it was from, and that it appeared to be a new SpearPhishing campaign. So naturally, I asked for a copy.

What I received was a "Trojan" (Trojan is in air quotes there) for the Mac. Something never seen before (as described by Virustotal) and was packaged up into a .zip file.

This .zip file contained an Application for the Mac (.app) with the familiar Finder icon. A couple of reports we received said that the program executed by double clicking it, however, in our test suite, the embedded binary did not execute.

This "Trojan" (as the trojan writer called it, I mean really... Trojan?) upon execution will display a PDF named "Survey.pdf", asking you to take a "Product Satisfaction Survey". Now, remember this was back in May. The VRT provided detection and protection for our AntiVirus customers (ClamAV and Immunet) as well as Snort detection at the time.

Fast forward to this past weekend when a new "PDF" (It wasn't a PDF, it just looked like a PDF, contrary to some new reports) document started making the rounds. As I said in the beginning of my story, I managed to get a hold of this "PDF Trojan" and took a look inside.

This new "Trojan" displayed a number of similarities to the other example we saw back in May. The same method for downloading other executables, a similar attack method, similar binary build methods, etc. Again the trojan wouldn't execute properly in our environment, some aspects of it functioned, and some didn't. Not a very good "Trojan" and certainly not as convincing as MacDefender.

In any case, ClamAV and Immunet customers are now protected against this malware:
  • MacOSX.Revir-1
Snort customers:
  • Sid:20202 <-> BOTNET-CNC OSX.Revir-1 outbound connection
  • Sid:20203 <-> BLACKLIST DNS request for known malware domain
As always, I'll keep reading the email from my lists, ever vigilant, keeping an eye open for the latest Mac malware, but if any of you reading this come across something, please get in touch with me or the VRT and let us know. The VRT contact information can be found here: To contact me directly, if you don't already know my email address, it is my first initial my last name at :D

Update:  After performing more research into the trojan, the original rules that were authored back in May also alert on this newest variant.  Ensure you have the following rules enabled as well:
  • Sid:19017 <-> BOTNET-CNC MacBack Trojan outbound connection attempt
  • Sid:19018 <-> BOTNET-CNC MacBack Trojan outbound connection attempt
  • Sid:19019 <-> BOTNET-CNC MacBack Trojan outbound connection attempt

Thursday, August 25, 2011

This is why we have nice things

A lot of people have been freaking out about the "Apache Killer" tool released on Full-Disclosure last Friday. While it's an effective way to cause a Denial of Service (DoS) against an Apache web server, and readily accessible to your average malfeasant, the good news is you don't need to let your hair catch fire over it, because the VRT had it covered before the tool was even released.

Specifically, the http_inspect preprocessor has an option to detect overly long header fields. Since the "Range:" header sent by the tool in order to exploit the bug is well over a packet's length in size, it easily triggers GID 119, SID 19 in Snort, which is set to go off for headers over 750 bytes in the standard open source configuration. For those using the Sourcefire corporate product, by default this option is set to 0 (disabled); this can of course easily be turned on, with a value as high as 1,500, and still catch the attack.

Meanwhile, we've included GID 1, SID 19825 in today's release, which looks for "Range:" headers broken in the specific way that this tool exploits. Not only will this make it easy to tell your boss you've got coverage in place for this crazy new tool, it will help anyone who may be in an environment where the long header preprocessor rule generates false positives.

You may now return to your regularly scheduled programming.

Tuesday, August 16, 2011

Rawbytes is not the modifier you're looking for

I spend a lot of time working with Sourcefire customers and open-source Snort users who write their own custom rules. Many of them are extremely astute, and some of them write rules good enough to be in the official VRT set. Others, well, not so much.

One of the biggest issues I see with custom rules is incorrect use of content modifiers. Missing out on the latest http_* buffer, of course, is totally understandable - the Snort team's constant refinement of that preprocessor has made a lot of things work better, even if it is occasionally a chore to keep up with. Mixing up depth, offset, distance, and within makes sense, too - everyone who writes Snort rules usually takes a little time to sort all those out in their brains. The one I don't understand at all, though, is people's obsession with rawbytes, especially in HTTP rules.

Seriously people, WTF? You're going out of your way to introduce rule evasion cases. The rawbytes modifier only exists because it was useful for some Telnet-related issues back in the day, and there are all of two rules outside the Telnet category that make use of it today - both of which are obscure edge cases where the rule is doing something truly unusual. No respectable Snort rule-writing class teaches you to use it; you've had to invest extra effort to even realize it exists, let alone decide to use it. Worst of all, using it to look at an HTTP header (or, heaven forbid, a URI) undoes all of the useful normalizations and de-obfuscation work done by the http_inspect preprocessor, making your rule "t%72iv%69a%6c" to avoid in the wild. Why waste your already limited time resources on breaking your rules?

So next time you think about including rawbytes in a rule, ask yourself this first: is there absolutely, positively, 100% for sure no other way to write this rule, and no chance I'm introducing an evasion in the process? If you can, without a doubt, answer yes to that question, sure, go right ahead and use rawbytes - we haven't deprecated it because the Internet is a strange place, and every so often you may run into a situation where you need it. If there's a shadow of a doubt in your mind, though, do IDSes around the world a favor, and just say no.

Friday, July 15, 2011

Do you really trust that certificate?

If you've read many of my posts on this blog, you've probably realized by now that I'm lazy when it comes to dealing with malware. I hate the "whack-a-mole" game of trying to stay on top of every new thing every new piece of malware does - not only because it'd keep me busy 24/7 if I tried to do that, but also because Snort would end up without particularly useful coverage anyway even if I (and a hundred of my closest friends) did.

With that in mind, I was pleased to add SID 19551 - "POLICY self-signed SSL certificate with default Internet Widgits Pty Ltd organization name" - to our last rule release (Issued on 2011-07-14). On the surface, it doesn't seem like it's related to malware at all - but if you'll give me a moment to explain, you may find yourself turning it on in the not-too-distant future.

The thought process behind it started with the barrage of requests I've received recently for coverage of the "indestructible" TDL4 botnet. One requester was kind enough to supply this excellent analysis from, which provided a list of recent C&C servers for this particular botnet. Armed with that information, I was able to go query up my malware sandbox, which had dozens of recently-run samples ready for analysis.

Sifting through the traffic, I noticed that, in addition to the custom encryption described in the analysis I'd read, successful connections to the C&C servers were starting off with SSL-encrypted traffic. Most people would be disheartened at the sight of this; I immediately zoomed in and looked at the server certificate, hoping that the botnet authors had used a unique Common Name in the certificates that we could use for an easy rule. Unfortunately, they had not; instead, they'd used the default option for a self-signed certificate, "Internet Widgits Pty Ltd".

As I sifted through the rest of the PCAPs, hoping to find a quality pattern, it dawned on me that even using the default option from a self-signed certificate was a useful indicator. Sure, most IT administrators use self-signed certs on their internal gear, and even some cheap administrators of low-traffic, public-facing sites will use them too (::looks at 21-year-old self::). Any serious, relevant site that uses SSL will have a validly signed certificate from a trusted CA - and even the cheapskates out there will usually set a non-default name on their self-signed certs.

With that in mind, we've made this rule available, just in case you agree with this logic and want to give this method of detection a spin. The rule is of course off by default, given that it could generate a substantial number of false positives (we'll be eager to get feedback from the field on just how many it generates, and what the ratio of useful-to-garbage alerts actually looks like). If you do decide to turn it on, I would recommend also checking that you've enabled SIDs 19496 - 19550, which look for DNS queries for the TLD4 C&C domains listed in the report I referenced above. If you see the two fire in rapid sequence, well, chances are real high you've got a problem on your hands.

P.S. Seems the good folks at had a similar idea the just a few days before we published that rule. I promise we didn't steal from them, it's just that great minds think alike. ;-)

Wednesday, July 13, 2011

Binary C&C Over HTTP

A few weeks ago I gave a presentation at the CARO 2011 Workshop in Prague. Besides being set in a stunningly beautiful location, the conference was an excellent opportunity to meet malware researchers from around the world - a group who are, by and large, distinct from network security researchers.

Since I personally happen to think that the separation of these two groups is a shame (and, well, since I needed a topic that would get me out to Prague in the springtime), my presentation crossed the proverbial streams, by looking at malware-generated network traffic. Thanks to the malware sandbox we have running over here, I've got traffic like that coming out my ears.

Specifically, the presentation focused on the presence of pure binary C&C channels being sent over HTTP. After the Night Dragon trojan (SIDs 18458/18459 for those keeping score at home) created a big media stir back in February, I was struck by the realization that sending data without HTTP headers over port 80 was actually a pretty solid trick, and that other malware authors might be doing something similar. After all, basically every firewall on the planet will let you initiate an outbound connection to the Internet on that port, and net flow sure isn't going to do much good on the busiest port on any network. Where better to be a needle in a haystack?

Running through approximately 1.5 million PCAPs from the sandbox, I realized that not only was this sort of thing happening among other malware families - it was actually fairly common. In fact, a full 0.8% of those 1.5 million samples showed this sort of behavior - a number which seems small, until you realize just how much malware you could catch with extremely simple behavioral analysis.

For those interested in more details, you can read my slides here. We are willing to share samples with legitimate security researchers - provided you're willing to send relevant data back our way in return.

For those just interested in protecting their networks - we're currently working with the Snort team to find the best way of detecting traffic like this at a generic level. In the meantime, I highly suggest that you enable SID 18492 - which looks for DNS queries made by the most prevalent bit of malware displaying this behavior in our sandbox - and that you consider turning on the entirety of our blacklist.rules and botnet-cnc.rules categories, which is where we're adding most of the new rules pulled from data generated by the sandbox.

Tuesday, July 12, 2011

Now Available -- Razorback 0.2 Release Candidate

0.2 Release Candidate

This week we’re putting out the Razorback 0.2 release candidate.  You can find it here:

This release, and the 0.2 final release scheduled for next week, contains all the major functionality for the dispatcher. The dispatcher in 0.2 now has the following capabilities:
  • Data acquisition and submission API
  • Alerting and judgment API
  • Queue based messaging system
  • Data blocks stored to disk
  • Support for local (shared file system) and over-the-wire data block transmission
  • Local and global caching services
  • MySQL database back-end
  • Remote management through the use of libcli

We use several open source services and libraries, so you’ll need to have those set up. The quick list is:
  • Apache's ActiveMQ
  • memcached (and associated libraries)
  • libcli
  • mysql (and associated libraries)
  • uuid libraries

Tom "The Amish Hammer" Judge has done a great job of laying out the prerequisites and other installation information on the Sourceforge Trac site here: After you have the prerequisites for installation, getting setup with a basic setup goes something like this:
  • tar -zxvf razorback-0.2rc.tar.gz
  • cd razorback
  • ./configure --prefix=/home/myhome/02rc/ --enable-debug --disable-officeCat --enable-routing-stats --disable-snort --disable-clamavNugget --with-api=/home/myhome/02rc/lib/
  • make; make install
  • Use the .sql scripts in ./dispatcher/share to setup schema and populate key data fields
  • cd /home/my home/02rc/etc/razorback
  • Change the names of *.config.sample to *.config
  • Change the name of magic.sample to magic
  • Edit dispatcher.conf
    • Modify database settings
    • Modify GlobalCache settings to point to your memcached server
    • Change username/password for the console
    • For now, leave everything else at default
  • Edit rzb.conf
    • Modify MessageQueue to point to your ActiveMQ server
  • cd /home/myhome/02rc/bin
  • ./dispatcher -d
    • Dispatcher should start up in debug mode
  • In another window, and in /home/myhome/02rc/bin:
    • ./masterNugget -d
    • master nugget and any nuggets you configured should start up in debug mode
  • In another window, and in /home/myhome/02rc/bin:
    • Find a PDF file
    • Inject it into the system:
      • /home/myhome/02rc/bin/fileInject  --type=PDF_FILE --file=monkey.pdf
    • A copy should be in your /tmp directory called block-.  This is done by the File Log nugget.
That test means your basic setup works.  We'll follow up with more information on the ClamAV and Snort-as-a-Collector nuggets in a future blog post, but both are functional for this build.  As always, you can get support from the Razorback trac site or from the Razorback mailing lists.

    Q3 -- Detection

    Now that we have the core of the system mostly in place, the Supreme High Royal Emperor Watchinski, head of the VRT, has declared that Q3 will be dedicated to building out the detection capability.  And there was much rejoicing.  (Seriously, the Dispatcher is awesome and all, but what we really want to do is detect bad things.  Its our thing.)

    To that end we'll be working towards several goals:
    • Script interface so that detection can be build in any given scripting language
    • A web portal so you can submit files to our Razorback deployment
    • A "Defense Run" where each developer works on two new nuggets for collection or detection
    • Improved configuration setup
    • A set of ISOs and VMWare images so you can quickly get the system up for testing.

    We'll keep you up to date on the Q3 stuff and we hope you let us know how you are doing with the 0.2RC.  You can expect a final release of the 0.2 build sometime next week, provided all goes well.

    Tuesday, June 28, 2011

    A Close Look at Rogue Antivirus Programs

    A couple of weeks ago I attended Hack In Paris (France, not Texas). It was a nice break from the crazy temperatures and humidity we had been experiencing in Washington, DC and I'm sure that all the attendees appreciated the fact that the conference took place on the grounds of Disneyland Paris. Given the excellent speakers at the conference, who covered various topics from smartphone security to Win32 exploit development, I enjoyed much more than nice weather and a great venue. This well-organized conference could easily become one of the premier European IT security conferences.

    I was happy to be selected to give a talk entitled "A Close Look at Rogue Antivirus Programs". You will find the PDF of the slides here.

    Please take a look. Any questions, comments, suggestions are welcome, either here, on twitter (@number007) or directly to me via email: azidouemba at sourcefire dot com.

    By the way, as if on cue, ChronoPay's co-founder Pavel Vrublevsky was arrested and held without bail on June 23, 2011 for allegedly hiring hackers to attack his company's rival. This arrest comes just 24h after authorities in the US and in seven other countries seized servers belonging to a hacking group behind a rogue AV campaign that netted them over $72 million.

    Tuesday, May 10, 2011

    MacDefender and its variants

    MacDefender showed up on the radar last week, as the first fake Anti-Virus (AV) ScamWare for MacOSX. Currently, its distributed under a couple of different names (that all display the same functionality); MacDefender, MacProtector, and "Mac Security". In the Windows world this flavor of malware has existed for years, enticing unsuspecting users into installing bogus AV software under the guise of the client machine being infected. Then once it scares you into believing you're infected, it asks for your credit card information in order to purchase the application that will "fix" the infection. In the Security realm we see this all the time on Windows systems, but I'm guessing the Mac user community doesn't have much experience with this type of scam.

    If you are one of the people that hasn't seen this type of scam before here is some technical information about how it works, what it does, and how to protect against it:
    1. “How did it find its way onto my machine?”
    2. MacDefender used a lot of SEO poisoning attacks to get their links in the top of various search engine's results. When you browse to one of these malicious sites a feature of Safari is used (the default browser on OSX) to automatically download the malware package containing this "MacDefender" software. This is possible, since the default configuration for Safari has "Open "safe" files after downloading" checked (by default) in their browser. This setting is under "Preferences" in Safari and is at the bottom of the "General" tab (the first tab). We recommend you uncheck this:
      uncheck tab
      Go ahead, we'll wait here.
    3. "Once it's downloaded"
    4. Like other pieces of "OSX malware" in the past, you have to open it (which the above checkbox will perform for you), then install it. This uses a normal looking OSX package installer, during which, you will have to type in your Admin credentials. Once you have done that it will install and initiate a fake antivirus scan of running processes and files on your system. It will then inform you that something is infected and needs to be cleaned up. So the basic scenario looks like this:
      • You use a search term in a web search engine (like Google or Bing)
      • You get your results, you click on one of the links in those results to read the information you are looking for
      • The webpage you landed on, unbeknownst to you, contains a link that downloads some malware and you are presented with the interface for an installer for some strange piece of software that you didn't intend to download, which requires your admin credentials to continue the installation
    5. "Now what?"
    6. Honestly, the GUI for this particular piece of malware looks very professional. The variants have different colored icons and such, but essentially, each version looks similar to this:
      It looks just like a genuine OSX application, because it is one, it was written using the same language and tools used by OSX developers all over the world. The purpose of course, unlike most applications, is nefarious. There aren't any telltale signs that it's actually malware. No words are misspelled, the grammar is acceptable to the casual reader. It makes use of proportionally spaced fonts, justified text and all the other niceties you would expect from a real product that has gone through a development, testing and QA cycle that genuine software is put through every day by software companies. Even some of the functionality you would expect from genuine AV software is replicated. For example, the scan window looks like it's going to do something productive:
      MacDefender scan
      In reality however, it doesn't actually scan your hard drive for anything. What it may do though, is open up "popup" windows in your browser to display some "interesting" NSFW web sites in order to make you think you are infected, and to further convince you to buy this program. (We didn't observe this functionality in our investigation though) The malware authors hope that this will scare you into purchasing the software. If you are sufficiently convinced, you take out your credit card, enter the information and are charged $79.95 for a "lifetime" protection. Given that most real AV packages for Windows normally charge between $20 and $50, this seems a little steep, but since the GUI looks good, it must do a good job and Mac users are used to spending a little more than their Windows counterparts for software, so I'm guessing the authors thought it would be a reasonable amount that a Mac user wouldn't mind paying.
      MacDefender cost
    7. "How can I remove it/prevent infection?"
      1. Uncheck "Open safe files", see #1 above.
      2. Open up "Activity Monitor" (this is in your Utilities folder within Applications)
      3. Find "MacDefender" (or whatever the malware is being called, MacProtector, Mac Security, etc)
      4. Highlight it then click "Quit Process" which looks like a big red stop sign at the top right of the Activity Monitor screen.
      5. Next, open System Preferences, and go to "Accounts". When it appears click on the "Login Items" button, select the program, and then click the "minus" button to remove it from Login Items.
      6. Next, navigate to your Applications folder, find the program, drag it to the trashcan, and then empty the trashcan. Yes. It's really that simple to remove.
    Today's SEU and rule release contains rules to detect existing infections. So, if you have Macs on your network, turn on GID 1, SIDs 18942 and 18943. Look for events from these two rules and if you see them, have the owner of the machine call their credit card company immediately.

    Also included in today's release is GID 1, SID 18944, which will generate events for network traffic that displays the characteristic signs of numerous known fake AV variants for both Windows and OSX. Let us know how that one works, we built that particular rule by analyzing more than 1000 samples of fake AV malware in our repository. The rule may generate some false positive events, so make sure to investigate your results carefully and send us the information. Use the form on here: to do so. (requires you to login with your account first)

    We issued ClamAV signatures for MacDefender several days ago and we will continue to update those as new variants are discovered. They are named:
    • Trojan.OSX.MacDefender
    • Trojan.OSX.MacDefender.B
    • Trojan.OSX.MacDefender.C
    The md5 sums for MacDefender and MacProtector:
    • 2f357b6037a957be9fbd35a49fb3ab72
    • a437eaafa5f90b15dbf98123e5dccf1c
    Finally, we recommend that you only buy software from reputable places, not from popup windows in your browser, and not from some random website you are currently viewing. Websites and advertisements on them, have been claiming to detect the presence of malware on PCs for a long time. It is one of the oldest tricks in the book and many people still fall for it. The Internet is akin to the old strip in Las Vegas, confidence tricksters and scam artists on every block, all looking to take money from gullible tourists. Don't be fooled, educate yourselves and your users, learn to recognize the scams and how to deal with them.


    Apple have now released information on how to remove this malware.
    Instructions are available here KB Article HT4650

    Tuesday, May 3, 2011

    Razorback Roadmap and Status Report

    In which we get our first introduction to Tom Judge, the Amish Hammer.

    Yep, you're right, we've been kinda quiet lately.  Some of that has been because we are the VRT in addition to the developers of Razorback and we had some big things to tackle in our other roles.  But we've also been just thinking and taking in some feedback.  We now have full time developers (and are still hiring, hint, hint) working on the project and we took the opportunity to revisit the architecture and, at a substantially more reasonable pace, decide if we were on track and where we wanted to go.  We have been working a lot on review and design, so you'll find this document somewhat lengthy.  Take a break after each list and go get some tea or something.

    First, we thought again about what our goals were for Razorback.  These are the first things that developers are told when they get here and a list we frequently reference when discussing architecture changes.  These are our initial goals:

    1.  Don't get in the user's way -- By this we mean that we don't make assumptions about a user's network or needs.  We don't want to make lazy decisions by making end users jump through hoops or have to work within unnecessary and opaque requirements.  The goal is to make a framework, not a prison.

    2.  Take care of the common stuff  -- We initially designed this system to allow talented people and teams to rapidly develop detection.  For example, many of the teams we talked to showed a particular (and not surprising) interest in web, mail and dns traffic.  Since this is a broad requirement, we added specific database tables and API calls to track these traffic types.

    3.  Hide nothing and never make the user duplicate work -- Ultimately this will be up to nugget builders, but we've provided the alerting and database framework so that every piece of analyzed information or normalized data can be stored and linked to the source files.  The classic example we use to explain to incoming developers what we mean by this is the PDF file.  If we decompress an object, store that object for the user in decompressed form.  If we analyze Javascript, fix it up and rename variables for ease of use, store that normalized Javascript block.  If we find shell code, store it separately and provide an explanation of what the shell code would do if it ran.

    4.  Build from the bottom up to scale big -- From the beginning we knew that this system, if implemented at any fairly sized network would require some horsepower.  We're taking the time to do work on arbitrary amounts of inbound data.  So we don't short cut code, we think about the speed impact up front and we minimize the work we do in the dispatcher.  It has a few discrete functions, and everything else is handed out to nuggets.  We continually review architecture for excessive network traffic, unnecessary scope creep and silly (some argue "clever") design decisions.  We have a strong admiration for the simple and a profound dislike for "magic".

    5.  Let the user do what he needs to do -- You might think this is covered under 1, but this addresses the core functionality of Razorback, as opposed to operational considerations.  We try to make every component, capability and user-facing operation configurable.  We try to ensure that we provide timely and readable logging.  But most of all, when it comes to detection, we want to let entities build on the framework to get it to do what they need it to do.  We know there are really smart people out there, and we want to let them be smart quickly.  So we provide user-definable flag fields in data-block, IP address, IP block, user and AS blocks to track information in an enterprise-specific way.  We allow analyst notes to be attached to just about any database entity.  We allow users to define their own data types that we route as easily as any of our provided types.  We allow arbitrary reporting.  In short, we want to be a framework, not a prison. (Yes, I know I'm repeating myself)

    So where is Razorback now?  We've got a 0.1.5 release tagged and available as a tarball up on sourceforge (  This is, pending something awesome in the way of a bug, the last of our development on the POC code we initially released at DEFCON last year.  It is fairly functional, and works well enough to demonstrate our thinking.  But we're in the midst of reimplementing it at a more sane pace, hopefully for the better.

    Sourcefire has given us not just developers, but also the time to continue this as a research application.  We have our final design pretty much laid out and we think we know where we're going.  But we have the leeway to spend time testing solutions, constantly refactoring code and proving to each other that we are headed in the right direction.  If we find we've developed ourselves into a corner, we'll be able to backup and rethink our approach.  We're taking full advantage of this.

    First, a caveat:  This is a list of things we hope to get done.  This is not a contract, this is not a guarantee.  But this is the way we're currently headed.  That being said, here is what we hope to get done this year:

    1. Packaging -- Razorback right now is ridiculously hard to install and configure.  Our goal is to build out a saner way to keep up with updates (all new files are in a single repository, not split between dispatcher and nuggets).  We also now provide a single configuration point to begin the build process.  We're also targeting a install process to help a new user get up to speed quickly so they can start playing.

    2. Security -- Both encryption and AAA services are being built into the system.  Authorization must occur at the earliest point possible and encryption options must be available for all traffic that could reveal data blocks, reporting or forensic data.  Also, silly implementation errors result in extreme mocking of developers and we hand over code to our tame hackers to generate more embarrassment.

    3. Networking -- IPv6 must be supported throughout the platform.  We must be nice to network operations folks and not transmit things on the network we don't have to.

    4. Operational interfaces --  Razorback 0.1.5 doesn't do a good job of communication at an operational level what is going on.  Incident response teams can get a lot of information, but the admin of the box is short on options to get insight into what is going on.  During architecture of components in the new build of Razorback, we're keeping a close eye on configuration options, verbose logging, metrics and fault-tolerance.  To assist in this, a real-time admin interface will be made available to the dispatcher.

    5. Data transfer -- We're implementing both caching and queueing services to ensure that we get data off of collectors as quickly as possible.  The queueing approach reflects the non-interactive nature of the collector-dispatcher-detection architecture and provides support for horizontal scaling.

    6. Database improvements -- I did the database schema which means two things:  1)  Its wrong and 2) Someone else needs to fix it.  We're going to work on building out a database interaction that is implementation agnostic.  We should support more than just MySQL.  The schema needs to be normalized to the maximum extend possible while ensuring it still supports enterprise-specific needs.  Also, we need to move to UTF-8 to support international language sets.

    7. API -- The API is going to be updated to support high-latency detection by returning to the dispatcher a deferred response.  This means that the nugget will take a while to process and the dispatcher should check back.  One example would be submission to a web-based analysis front end.  The nugget would store the information necessary to return to that site later in the dispatcher.  The dispatcher would manage a queue of deferred detection so any compatible nugget can pull from the queue and query the website to see if the response is ready.

    8. Scripting -- So I was jacking around with Maltego and I built some custom database connectors.  The way they allow this is you call something and pass arguments via stdin and then return results via stdout and stderr.  It is genius in its simplicity and ease of implementation.  This allows us to provide scripting support under any language provided they accept and return data in well-formed blocks.  This is actually one of my favorite updates and should help response teams rapidly roll out detection.

    9. Data storage -- We store the binary data blocks in the relational database.  There are many ways to describe this practice, but the way Watchinski (our boss) described by somehow simultaneously rolling his eyes, laughing like a hyena and demanding we fix it.  As it works out, this was my idea.  So we're looking at a number of solutions for data storage from the mundane (FTP, HTTP) to the exotic(ish) NoSQL and map-reduce sort of things.  This is a key research area because we want to allow searching of files to find indicators of compromise, etc...  This change will also affect how we submit data to the system, so we aren't clogging up the dispatcher with huge blocks of data while we wait for processing.

    10. Scalability -- This is a late-year requirement, but we want to go huge with wide sets of dispatchers and deep sets of detection.  There isn't really a timeline for this, but development is going on with an eye towards this requirement.

    So...that's our small list of things we're up to.  We're working on two-to-four-week development cycles and we will be releasing stable (for some value of stable) tarballs each quarter.  The Q2 release is already being built and currently is in trunk.  The Q2 dev cycle is laid out like this:

     — Implement and prove end-to-end data transfer via the queueing system and updated API

     — Implement and prove database and local and global caching systems that relate to datablock handling

     — Architect and implement the response capability for detection nuggets including alerting and data block judgement

     — Provide preliminary support for large data-block transfers to dedicated file storage and notification to detection systems to pull the block instead of getting it over the queue

     Don't go for tea now, we're almost done.  You can do it!)

    We've finished phase 1 and are working on design and testing requirements for phase 2.  Our goal is to have all of these completed by the end of June.  Phase one uses ActiveMQ and the Stomp protocol to manage data transmission and command and control.  This allows us to use the ActiveMQ authentication system so that nuggets can not communicate to the system unless they have the proper credentials.  Routing is also functional now, with multiple data types routing to multiple application types.  We also now support the "any" data type so that a nugget will receive any data that is provided to the system.  This supports logging nuggets and anti-virus solutions.

    Well, that is where we are and where we think we're headed.  We'll let you know when we have an RC for the Q2 release, and as we flesh out specific requirements for future releases we'll provide those as well.  In the meantime, checkout the outstanding documentation provided by Mr. Tom Judge, our newest developer and total svn ninja.  It lays out everything you need to know about the code currently being worked on in trunk.  You can find it at

    This is an open source project, if you want to contribute code either in the form of nuggets or other functionality, we welcome your participation.  If you have a question or comment about either participating in the development of the project or the project road map hit the mailing list, we'd love to hear from you.

    Tuesday, April 5, 2011

    Lizamoon attacks and generic detection

    You've probably heard by now of the "Lizamoon" attacks, a rapidly spreading bit of SQL injection named for the domain that hosted the script dropped onto a variety of pages across the web. While not a particularly interesting attack from a technical perspective, it's hit enough hosts to be a nuisance, and to get IT managers up in arms about protecting against it.

    The good news for anyone running a Sourcefire/Snort box is that, if you've paid attention to this blog in the past, you're already covered. SID 13989, which I referenced in my "Known Unknowns: The 'Don't Do That' Rules" post last May, is the rule you want to make sure is enabled. Originally written to deal with SQL injection attacks similar to the Asprox trojan, it has the handy benefit of picking up a number of different SQL injection attacks that are being obfuscated via use of the char() function (which is exactly how Lizamoon works). Given the lack of false positive reports from the field, and its apparent usefulness in detecting new attacks, we'll be enabling that rule in some of our default policies going forward.

    In the meantime, SID 18604 will be released in the next SEU to detect the code dropped onto infected web sites. While that rule is less generic, and thus less likely to pick up entirely different families of malware in the future, it should at least keep your pointy-headed bosses happy when they ask if you're safe from this newfangled Lizamoon thingee.

    Tuesday, March 29, 2011

    Razorback - Whats going on?

    Its been almost 3 weeks since I joined the VRT and started working on Razorback. Over that time we have made some good progress with the project and I wanted to share what we have done and what we are going to be working on over the next few weeks.
    What we have completed so far:
    1. Subversion repository restructure:
      We have restructured the subversion repository in a way that has given us the following:
      • The ability to build components separately with minimal cross project dependencies.
      • The ability to release individual components of the system in separate tarballs, this is geared towards binary package maintainers.
      • The ability to release a jumbo tarball with all of the razorback components in them for rapid deployment.
      More information on the new repository structure can be found the in Developers Guide here: Layout
    2. Integration of all nuggets from the nugget farm project into the main project:
      All of the nuggets that where in the nuggetfarm project on SourceForge have been pulled into the main project. The aim of is is to make it simpler to maintain the official nuggets. These nuggets are now available in the full release tarball or as individual components.
    3. API Project Improvements:
      • The API has been split out of the dispatcher project to make it easier to maintain.
      • API library symbol visibility - lots of the other components (disptacher and nuggets) required an un-installed build of the API to be available to them so that they could statically link in a sub library that was not installed; the utils library. The should allow people to build components much easier if they have installed the system from packages or from the per component release tarballs.
    4. New/Improved configuration API.
      • We have replaced the hand rolled parser with libconfig (, which has drastically reduced the time that it takes to add configuration items to components.
      • We have also added routines to allow components to use the configuration api to load configuration files that they specify the structure of simply and in a standard fashion. This has allowed us to remove all hard coded configuration items from nuggets and put them into configuration files.
      • The configuration API now looks for configuration files in the configured sysconfdir by default, the API calls allow you to pass custom search locations in if required. This means that you no longer have to run every command with --conf=... which may be a relief to many of you.
      You can read up on the new configuration API here:
    5. Doxygen API Documentation:
      We have started using doxygen to generate up to date API documentation and publish it to the project website. Documentation is generated and published every 4 hours for supported branches. Not all files have been fully documented yet but you can find out about what has been here:
    6. Continuous integration testing.
      As of the 0.1.5 release we have defined the officially supported platforms to run Razorback on and the architectures that we support for those platforms. These are currently set out as the following base OS’s running on either i386 or amd64/x86_64 hardware:
      • Debian 6.0
      • FreeBSD 8.1
      • RedHat Enterprise Linux 6.0
      • Ubuntu 10.04 LTS
      In order to help maintain compatibility across these platforms and to reduce the amount of times developers spend testing on these platforms we have deployed BuildBot. BuildBot is a continuous integration system that will run a sequence of actions when an event triggers them. Currently we have it setup to build every component on every platform after 15 minutes of idle time in the repository after a commit. In addition to this the system will trigger builds of the API if something that depends on it changes, or of all the things that depend on the API if a change is made to it. You can read more about buildbot here:
    7. System Manual and Developers Guide
      We have started writing better user and developer documentation for the system, with the aim of allowing more people to be able to setup and use the system. This information is available on the project wiki:
    8. Nugget cleanup:
      We have cleaned up and packaged all of the nuggets so that they are easy to install and simple to configure. Where applicable we have integrated 3rd party libraries and components into the nuggets to make them faster to install.
    What's coming next? Here is a short list of the most exciting features being worked on (in no particular order):
    • Complete redesign of the dispatcher.
    • IPv6 Support for inter-component communication .
    • Encryption support for data passing between components.
    • API Improvements for none real time processing.
    • Database improvements.
    • Data block storage and transfer improvements.

    Thursday, March 3, 2011

    Attack Obfuscation - Not Just For JavaScript

    Since his company purchased a Sourcefire IPS setup last summer, I've had a close working relationship with Mickey Lasky, the primary network security analyst at a company (which shall intentionally remain unnamed) that runs a number of public-facing web sites. He sends me PCAPs whenever he runs across something especially weird, and I help him with custom rules in return. Mickey also runs experimental rules for me from time to time, which is quite useful since the network he's protecting is especially busy, and if there's going to be a false positive, it'll show up there.

    A couple of weeks ago, he sent me a particularly interesting set of PCAPs, saying that he'd collected them after discovering that a single, determined intruder was busy dropping malware on the web servers he's watching over by uploading PHP code to them via POST requests. By itself, that's not all that exciting; what I found interesting was the way the attacker had obfuscated the requests. In addition to lots of Base64-encoded data, there were large chunks of code that looked like this:
    $wWfdGw['_HG3uWD_']=Array('ob'    .  '_en'.'d_flus'.  'h');      $kITFJjggfl=Array();
    function    HG3uWD($ownentes83)
    global  $kITFJjggfl;    $rdupmKoww  =    'c'."hr";
    $aaSbVPTgxM   =  $rdupmKoww(98) .   $rdupmKoww(97) .'se'  . 
    $rdupmKoww(54)."4_decode";$postimagistes    =  $rdupmKoww($aaSbVPTgxM('MTA=')).   $rdupmKoww(13)
    .' '   .   $rdupmKoww($aaSbVPTgxM('MzM='))   .    $rdupmKoww(35)  .    '%'.    $rdupmKoww(38)
    .$rdupmKoww($aaSbVPTgxM('NDA=')) .   ')'  .
    Since the variable names changed from one POST to another - as did the way the code sliced up underlying strings like "chr" or, in other places, "base64_decode" - the question became, is there any generic characteristic across all of these attacks that could be used to write a rule, which would simultaneously not generate massive false positives on normal traffic?

    What immediately sprung to mind was the odd spacing surrounding the concatenation operators, or "."s. In normal PHP code, string concatenation generally looks like:
    $longvar = $var1 . $var2;
    $longvar = $var1.$var2;
    There's no rational reason for a human to surround the "." with more than one space on either side, and certainly not a random number ranging up to five spaces on either side. Automated code generators wouldn't do spacing like that either. That led to an easy rule:
    alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"WEB-PHP generic PHP code obfuscation attempt"; flow:established,to_server;
    content:"|20 20 20 20 2E|"; content:"|20 20 20 20 2E|"; distance:0; classtype:trojan-activity;)
    The problem with this rule, we quickly found, was that since some of the web sites being monitored allowed code uploads, CSS files ended up heading towards port 80 on the network being monitored. When those files used spaces instead of tabs for declarations, a la:
    .calendar-date-switcher {
    They matched the initial signature and caused a bunch of false positives, rendering the rule useless for blocking mode.

    Going back to the drawing board, I realized that some of the built-in PHP keywords were never obfuscated in these attacks - in particular, Array(). Since CSS doesn't declare arrays like that, the rule quickly became:
    alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"WEB-PHP generic PHP code obfuscation attempt"; flow:established,to_server;
    content:"Array|28|"; content:"|20 20 20 20 2E|"; within:200; classtype:trojan-activity;)
    After 24 hours of testing, Mickey determined that the false positives had been eliminated, and that the rule was still catching the attacker's POST requests, so he turned it on in inline mode. Suddenly the attacks stopped succeeding, and the rule was lighting up his console like a hyperactive pinball machine.

    While this same attacker has continued to look for other ways to drop his code on Mickey's systems, I've reached out to other contacts running large production networks, and found that the false positive rate of that rule is essentially none. Armed with that knowledge, we've released it as SID 18493 in today's SEU. Though it's disabled by default, as are other similar obfuscation-detection rules, we would encourage you to give it a shot if you're interested. It may be that this particular technique is confined to this specific attacker, but since the rule is high-performance and apparently high-fidelity, the risk to reward ratio on it seems favorable to us, just in case.

    Tuesday, February 8, 2011

    Blacklist.rules, ClamAV, and Data Mining

    We've received a number of queries recently about the source of the data in the blacklist.rules category. I'm posting the answer here, since it will be of broad interest to the Sourcefire/Snort user base.

    One of the side effects of our 2007 acquisition of the ClamAV project was the VRT gaining access to the ClamAV database. This massive collection of malware, augmented by tens of thousands of unique samples per day from a variety of sources, is a treasure trove of information - assuming you can find a useful way to sift through it all. Thanks to the magic of the VMWare API, I've developed a system that does precisely that, with a focus on network traffic instead of the traditional anti-virus interest in the malicious files themselves.

    The setup starts with some big, beefy chunks of hardware, running VMWare ESXi Server. For each of these machines, there is a single Ubuntu-based VM that serves as a NAT/controller box, and as many freshly installed Windows XP SP2 (unpatched) systems as the hardware can support. The controller systems each run scripts that automatically pull the latest executable samples from the ClamAV database, and then farm them out in a systematic way to the XP systems, following this simple procedure:
    1. Revert XP VM to clean snapshot
    2. Copy malware sample to XP VM
    3. Fork off tcpdump in the background on the controller, with a BPF specific to the XP VM in question
    4. Execute the malware sample on the XP VM
    5. Wait 150 seconds
    6. Repeat step 1
    Simple as the process seems, it's taken some time to get it running smoothly. At first, we thought RAM would be our bottleneck; as it turns out, disk access time was a considerably more important factor, as the process of constantly reverting machines to a clean snapshot is very I/O intensive. We've had to fine-tune our queue management process, since the rate of growth in new malware samples is outstripping our hardware's ability to process them. Parsing through all of the PCAPs generated by the system required learning, and eventually patching, tshark, the command-line PCAP processing tool from the good folks at (yes, we submitted the patch back). After a not-inconsiderable amount of time getting everything set up, this system has been happily churning through malicious executables from ClamAV for several months now.

    As the data came rolling in, we knew we'd need to whitelist things out before creating rules from what we saw. Given that all of the network traffic generated by this system comes directly from infected machines, with no human interaction, we figured that the whitelisting process would be pretty straightforward - aside from the occasional ping to to verify connectivity to the Internet, the initial expectation was that most of the traffic would be command-and-control, or at least talking to clearly not-legitimate systems. Surprisingly enough, however, a huge portion of the HTTP traffic in these PCAPs - which in turn represents the vast bulk of the traffic captured - went to legitimate domains, including thousands of relatively obscure ad servers across the world. Separating these domains from truly malicious sites has been one of the more interesting ongoing challenges in running this system.

    Since the goal is to generate data that's useful for the largest possible number of users, the domains and URLs that make up the end-product rules are those accessed most frequently by our system's infected machines. Looking for the most commonly accessed places has a side benefit of helping to filter out highly transient endpoints and behaviors - the domains and URLs in question are often being accessed thousands of times over the course of weeks or months by our victim machines, and rules that we released last year are still helping users identify and clean out infected machines on their network. As of the Feb. 8, 2011 rule release, we're also including rules for abnormal User-Agent strings generated by our systems, taking advantage of malware authors dumb enough to set the HTTP equivalent of the Evil Bit as they talk to systems around the Internet.

    In addition to the rules we publish, we're also automatically publishing chunks of raw data from this malware system on the VRT Labs site on a daily basis. As a word of caution to anyone considering simply pulling those lists of IPs, URLs, and domains down and adding them to an internal blacklist: your mileage may vary rather drastically. While we do filter those lists, they don't receive the level of human attention and verification that the data going into the rules gets, and consequently they are much, much more likely to contain false positives. As such, we would suggest cross-referencing them with other data sets, or applying other filtering techniques your organization may have, before using them to block data in your enterprise.

    Obviously, there is room for improvement in this system; we know, for example, that there is a lot of malware that will detect virtual machines and refuse to run, or that there is additional data we could be pulling from the PCAPs the infected systems generate. That said, we feel that it provides considerable value to our users as-is, and we will be continuing to work to improve it as time goes on. In the meantime, if anyone has suggestions for us, please don't hesitate to contact the VRT - your feedback is always valuable!

    Monday, January 10, 2011

    In which kpyke looks behind the green curtain

    From an operations perspective, there is very little that is less useful and more aggravating than vendor magic. What I mean by this is anything that "happens" in the background that you have no visibility into. While many organizations enjoy the simplicity provided by this, when you need to McGyver some solution to a security issue that vendors haven't addressed yet, you just might feel like simply setting fire to equipment that got in your way. Not that I'm endorsing that.

    This is one of the main strengths of open source software. If you know what you're doing, you can uncover all the magic so you know exactly what you're dealing with and you can fix it up if you need to. Snort-wise, one of the things that it does in the background for you is normalize data and put it into various buffers. At one point the list of buffers was fairly small: normalized and raw. At this point you have the following buffers:

    BufferInternal RepresentationNotes *

    normalizedCONTENT_BUF_NORMALIZEDThis is the default buffer that Snort matches against.  Also contains gzip decoded data.
    rawCONTENT_BUF_RAWNot used often, mainly for looking at non-normalized TELNET and FTP data.
    http_cookieCONTENT_BUF_COOKIEConfig option required to activate cookie parsing.
    http_methodCONTENT_BUF_METHODParsed from header, not normalized.
    http_stat_codeCONTENT_BUF_STAT_CODEParsed from header, not normalized.
    http_stat_msgCONTENT_BUF_STAT_MSGParsed from header, not normalized.
    file_data:mimeBUF_FILE_DATA_MIMEBuffer holds the mime decoded data for SMTP
    file_dataBUF_FILE_DATANot actually a buffer, but a pointer into normalized buffer
    * see the labs_buffers.c file for additional commentary on the buffers

    Buffers aren't the only place where Snort massages the data.  Both fragmentation and stream reassembly occur and can impact detection.  So between parsing, normalization, defragmentation and stream reassembly, the final data blob looked at by Snort can be significantly different than what you see on Wireshark.  This can make rule writing and debugging difficult.  To help with this I've written a set of .SO rules that print out the buffers exactly as Snort views them for each packet in a PCAP.  They've been really useful, so we're releasing them on the VRT Labs site (currently tested against Snort, so don't yell at me if it doesn't work on anything before that).

    Once you download them, move them to your .SO directory and modify the following line in your Makefile:
    libs := icmp p2p dos exploit bad-traffic web-activex web-client web-iis netbios misc nntp smtp web-misc sql imap chat multimedia pop3
    libs := labs
    Then run "make", and modify your Snort conf to include the new labs.rules file.  It should be something like:
    include $RULE_PATH/../so_rules/labs.rules
    The labs.rules file should look like this:
    # Autogenerated skeleton rules file.  Do NOT edit by hand
    alert tcp any any -> any any (msg:"VRT LABS: All Ports Two-Way Packet Description"; sid:100005; gid:3; rev:1; classtype:misc-activity; metadata: engine shared, soid 3|100005;)
    alert tcp any any -> any $HTTP_PORTS (msg:"VRT LABS: HTTP_PORTS Client to Server Packet Description"; sid:100000; gid:3; rev:1; classtype:misc-activity; metadata: engine shared, soid 3|100000;)
    alert tcp any $HTTP_PORTS -> any any (msg:"VRT LABS: HTTP_PORTS Server to Client Packet Description"; sid:100001; gid:3; rev:1; classtype:misc-activity; metadata: engine shared, soid 3|100001;)
    alert tcp any any -> any 25 (msg:"VRT LABS: SMTP Client to Server Packet Description"; sid:100111; gid:3; rev:1; classtype:misc-activity; metadata: engine shared, soid 3|100111;)
    To get started, I would recommend commenting out all but the first rule.  This will show you all the goodies you need.  When you're working specifically with http data, I'd enable one or both of the second and third rules.  Finally, when looking at SMTP client-to-server traffic (where you'll see mime-decoded data), you can enable only the fourth rule.  If you have all rules on, you'll get multiple decoding (probably two per packet).

    Hey, listen up:  This is only designed to be run on pcap files with TCP data, where you have all the time in the world to read, parse and write data.  If you run this on a running sensor it will probably melt, so don't.  Also, it is what it is, so don't run it on anything important.

    Each packet will start with a header as follows:
    ******************************  NEW PACKET  *****************************
    Timestamp: 2009-08-27 18:08:29:16274
    Src IP:
    Dst IP:
    TCP Flags: ACK
    The top line lets you know you have a new packet (easy to miss if you have a lot of data) and then you have a time-stamp (conveniently formatted in Wireshark format) and more IP/TCP header information.  If this is a pseudo packet rebuilt by the stream5 preprocessor, you see this instead of the NEW PACKET line above:
    ************************  NEW REASSEMBLED PACKET  ***********************
    Then we start pulling apart the buffers.  First we check if there is data, and if there isn't any, we simply write:
    [-No data in this packet-]
    Otherwise we write the raw buffer out and check to see if the normalized buffer is different than the raw buffer.  If it isn't, you'll see the raw packet data and then:
    If the data isn't the same, it will print the normalized data.

    After this we get into specificly parsed buffers.  After the jump, we have two packets that are an example of a packet broken out.  It is a client request and server response over http, so you can see how we break things out:

    ******************************  NEW PACKET  *****************************
    Timestamp: 2009-08-27 18:08:28:886026
    Src IP:
    Dst IP:
    TCP Flags: PSH ACK
    ******  BUFFER INFORMATION  ******
    [RAW BUFFER DATA (0xacc1fe0)]:
    0x0000  47 45 54 20 2f 41 14 41 41 41 41 2f 63 6f 6e 66  GET /AAAAAA/conf
    0x0010  69 67 32 2e 62 69 6e 20 48 54 54 50 2f 31 2e 31  ig2.bin HTTP/1.1
    0x0020  0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 55  ..Accept: */*..U
    0x0030  73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f 7a 69 6c  ser-Agent: Mozil
    0x0040  6c 61 2f 34 2e 30 20 28 63 6f 6d 70 61 74 69 62  la/4.0 (compatib
    0x0050  6c 65 3b 20 4d 53 49 45 20 37 2e 30 3b 20 57 69  le; MSIE 7.0; Wi
    0x0060  6e 64 6f 77 73 20 4e 54 20 35 2e 31 29 0d 0a 48  ndows NT 5.1)..H
    0x0070  6f 73 74 3a 20 31 39 35 2e 32 2e 32 35 33 2e 39  ost:
    0x0080  35 0d 0a 50 72 61 67 6d 61 3a 20 6e 6f 2d 63 61  5..Pragma: no-ca
    0x0090  63 68 65 0d 0a 0d 0a                             che....
    [HTTP_HEADER BUFFER DATA (0x8b1fb00)]:
    0x0000  41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 55 73 65  Accept: */*..Use
    0x0010  72 2d 41 67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61  r-Agent: Mozilla
    0x0020  2f 34 2e 30 20 28 63 6f 6d 70 61 74 69 62 6c 65  /4.0 (compatible
    0x0030  3b 20 4d 53 49 45 20 37 2e 30 3b 20 57 69 6e 64  ; MSIE 7.0; Wind
    0x0040  6f 77 73 20 4e 54 20 35 2e 31 29 0d 0a 48 6f 73  ows NT 5.1)..Hos
    0x0050  74 3a 20 31 39 35 2e 32 2e 32 35 33 2e 39 35 0d  t:
    0x0060  0a 50 72 61 67 6d 61 3a 20 6e 6f 2d 63 61 63 68  .Pragma: no-cach
    0x0070  65 0d 0a 0d 0a                                   e....
    [HTTP_HEADER_RAW BUFFER DATA (0xacc2002)]:
    0x0000  41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 55 73 65  Accept: */*..Use
    0x0010  72 2d 41 67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61  r-Agent: Mozilla
    0x0020  2f 34 2e 30 20 28 63 6f 6d 70 61 74 69 62 6c 65  /4.0 (compatible
    0x0030  3b 20 4d 53 49 45 20 37 2e 30 3b 20 57 69 6e 64  ; MSIE 7.0; Wind
    0x0040  6f 77 73 20 4e 54 20 35 2e 31 29 0d 0a 48 6f 73  ows NT 5.1)..Hos
    0x0050  74 3a 20 31 39 35 2e 32 2e 32 35 33 2e 39 35 0d  t:
    0x0060  0a 50 72 61 67 6d 61 3a 20 6e 6f 2d 63 61 63 68  .Pragma: no-cach
    0x0070  65 0d 0a 0d 0a                                   e....
    [HTTP_URI BUFFER DATA (0xacc1fe4)]:
    0x0000  2f 41 41 41 41 41 41 2f 63 6f 6e 66 69 67 32 2e  /AAAAAA/config2.
    0x0010  62 69 6e                                         bin
    [HTTP_URI_RAW BUFFER DATA (0xacc1fe4)]:
    0x0000  2f 41 41 41 41 41 41 2f 63 6f 6e 66 69 67 32 2e  /AAAAAA/config2.
    0x0010  62 69 6e                                         bin
    [HTTP_METHOD BUFFER DATA (0xacc1fe0)]:
    0x0000  47 45 54                                         GET
    **********  END PACKET  **********
    ****************************** NEW PACKET *****************************
    Timestamp: 2009-08-27 18:08:29:16274
    Src IP:
    Dst IP:
    TCP Flags: ACK
    ****** BUFFER INFORMATION ******
    [RAW BUFFER DATA (0xacc1fe0)]:
    0x0000 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
    0x0010 0a 44 61 74 65 3a 20 54 68 75 2c 20 32 37 20 41 .Date: Thu, 27 A
    0x0020 75 67 20 32 30 30 39 20 30 37 3a 34 39 3a 33 30 ug 2009 07:49:30
    0x0030 20 47 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70 GMT..Server: Ap
    0x0040 61 63 68 65 2f 32 2e 32 2e 31 31 20 28 46 72 65 ache/2.2.11 (Fre
    0x0050 65 42 53 44 29 20 6d 6f 64 5f 73 73 6c 2f 32 2e eBSD) mod_ssl/2.
    0x0060 32 2e 31 31 20 4f 70 65 6e 53 53 4c 2f 30 2e 39 2.11 OpenSSL/0.9
    0x0070 2e 37 65 2d 70 31 20 44 41 56 2f 32 20 50 48 50 .7e-p1 DAV/2 PHP
    0x0080 2f 35 2e 32 2e 38 20 77 69 74 68 20 53 75 68 6f /5.2.8 with Suho
    0x0090 73 69 6e 2d 50 61 74 63 68 0d 0a 4c 61 73 74 2d sin-Patch..Last-
    0x00a0 4d 6f 64 69 66 69 65 64 3a 20 57 65 64 2c 20 32 Modified: Wed, 2
    0x00b0 36 20 41 75 67 20 32 30 30 39 20 31 38 3a 30 39 6 Aug 2009 18:09
    0x00c0 3a 34 33 20 47 4d 54 0d 0a 45 54 61 67 3a 20 22 :43 GMT..ETag: "
    0x00d0 61 61 30 32 62 33 2d 63 37 63 34 2d 34 37 32 30 aa02b3-c7c4-4720
    0x00e0 66 35 61 66 36 32 37 63 30 22 0d 0a 41 63 63 65 f5af627c0"..Acce
    0x00f0 70 74 2d 52 61 6e 67 65 73 3a 20 62 79 74 65 73 pt-Ranges: bytes
    0x0100 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 ..Content-Length
    0x0110 3a 20 35 31 31 34 30 0d 0a 43 6f 6e 74 65 6e 74 : 51140..Content
    0x0120 2d 54 79 70 65 3a 20 61 70 70 6c 69 63 61 74 69 -Type: applicati
    0x0130 6f 6e 2f 6f 63 74 65 74 2d 73 74 72 65 61 6d 0d on/octet-stream.
    0x0140 0a 0d 0a f2 2a 25 3f 37 50 e7 02 09 f5 10 cf 63 ....*%?7P......c
    0x0150 47 4e 5f 2a b3 ac 05 b6 fe 42 cd fe c0 9a ec 6f GN_*.....B.....o
    0x0160 bb 3c 98 d5 75 f7 6a 61 6c 30 88 6a 5c e5 20 65 .<..u.jal0.j\. e
    0x0170 75 6f 51 ba 91 63 61 52 5a c8 91 cd 79 84 7e 96 uoQ..caRZ...y.~.
    0x0180 96 58 e1 3e 20 f8 04 12 82 61 59 1e b6 18 d1 9b .X.> ....aY.....
    0x0190 56 3b f3 e7 5b bb 12 66 10 19 92 8e f8 e1 d0 ea V;..[..f........
    0x01a0 42 77 fd 8e a7 4e 0e 1f fa 83 32 f6 df 9c 91 79 Bw...N....2....y
    [HTTP_HEADER BUFFER DATA (0x8b24b00)]:
    0x0000 44 61 74 65 3a 20 54 68 75 2c 20 32 37 20 41 75 Date: Thu, 27 Au
    0x0010 67 20 32 30 30 39 20 30 37 3a 34 39 3a 33 30 20 g 2009 07:49:30
    0x0020 47 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70 61 GMT..Server: Apa
    0x0030 63 68 65 2f 32 2e 32 2e 31 31 20 28 46 72 65 65 che/2.2.11 (Free
    0x0040 42 53 44 29 20 6d 6f 64 5f 73 73 6c 2f 32 2e 32 BSD) mod_ssl/2.2
    0x0050 2e 31 31 20 4f 70 65 6e 53 53 4c 2f 30 2e 39 2e .11 OpenSSL/0.9.
    0x0060 37 65 2d 70 31 20 44 41 56 2f 32 20 50 48 50 2f 7e-p1 DAV/2 PHP/
    0x0070 35 2e 32 2e 38 20 77 69 74 68 20 53 75 68 6f 73 5.2.8 with Suhos
    0x0080 69 6e 2d 50 61 74 63 68 0d 0a 4c 61 73 74 2d 4d in-Patch..Last-M
    0x0090 6f 64 69 66 69 65 64 3a 20 57 65 64 2c 20 32 36 odified: Wed, 26
    0x00a0 20 41 75 67 20 32 30 30 39 20 31 38 3a 30 39 3a Aug 2009 18:09:
    0x00b0 34 33 20 47 4d 54 0d 0a 45 54 61 67 3a 20 22 61 43 GMT..ETag: "a
    0x00c0 61 30 32 62 33 2d 63 37 63 34 2d 34 37 32 30 66 a02b3-c7c4-4720f
    0x00d0 35 61 66 36 32 37 63 30 22 0d 0a 41 63 63 65 70 5af627c0"..Accep
    0x00e0 74 2d 52 61 6e 67 65 73 3a 20 62 79 74 65 73 0d t-Ranges: bytes.
    0x00f0 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a .Content-Length:
    0x0100 20 35 31 31 34 30 0d 0a 43 6f 6e 74 65 6e 74 2d 51140..Content-
    0x0110 54 79 70 65 3a 20 61 70 70 6c 69 63 61 74 69 6f Type: applicatio
    0x0120 6e 2f 6f 63 74 65 74 2d 73 74 72 65 61 6d 0d 0a n/octet-stream..
    0x0130 0d 0a
    [HTTP_HEADER_RAW BUFFER DATA (0xacc1ff1)]:
    0x0000 44 61 74 65 3a 20 54 68 75 2c 20 32 37 20 41 75 Date: Thu, 27 Au
    0x0010 67 20 32 30 30 39 20 30 37 3a 34 39 3a 33 30 20 g 2009 07:49:30
    0x0020 47 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70 61 GMT..Server: Apa
    0x0030 63 68 65 2f 32 2e 32 2e 31 31 20 28 46 72 65 65 che/2.2.11 (Free
    0x0040 42 53 44 29 20 6d 6f 64 5f 73 73 6c 2f 32 2e 32 BSD) mod_ssl/2.2
    0x0050 2e 31 31 20 4f 70 65 6e 53 53 4c 2f 30 2e 39 2e .11 OpenSSL/0.9.
    0x0060 37 65 2d 70 31 20 44 41 56 2f 32 20 50 48 50 2f 7e-p1 DAV/2 PHP/
    0x0070 35 2e 32 2e 38 20 77 69 74 68 20 53 75 68 6f 73 5.2.8 with Suhos
    0x0080 69 6e 2d 50 61 74 63 68 0d 0a 4c 61 73 74 2d 4d in-Patch..Last-M
    0x0090 6f 64 69 66 69 65 64 3a 20 57 65 64 2c 20 32 36 odified: Wed, 26
    0x00a0 20 41 75 67 20 32 30 30 39 20 31 38 3a 30 39 3a Aug 2009 18:09:
    0x00b0 34 33 20 47 4d 54 0d 0a 45 54 61 67 3a 20 22 61 43 GMT..ETag: "a
    0x00c0 61 30 32 62 33 2d 63 37 63 34 2d 34 37 32 30 66 a02b3-c7c4-4720f
    0x00d0 35 61 66 36 32 37 63 30 22 0d 0a 41 63 63 65 70 5af627c0"..Accep
    0x00e0 74 2d 52 61 6e 67 65 73 3a 20 62 79 74 65 73 0d t-Ranges: bytes.
    0x00f0 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a .Content-Length:
    0x0100 20 35 31 31 34 30 0d 0a 43 6f 6e 74 65 6e 74 2d 51140..Content-
    0x0110 54 79 70 65 3a 20 61 70 70 6c 69 63 61 74 69 6f Type: applicatio
    0x0120 6e 2f 6f 63 74 65 74 2d 73 74 72 65 61 6d 0d 0a n/octet-stream..
    0x0130 0d 0a ..
    [HTTP_STAT_CODE BUFFER DATA (0xacc1fe9)]:
    0x0000 32 30 30 200
    [HTTP_STAT_MSG BUFFER DATA (0xacc1fed)]:
    0x0000 4f 4b 0d 0a OK..
    ********** END PACKET **********

    I have some things left to do on this. For example, raw buffers that are the same as their normalized buffers don't need to be printed. As we update things, we'll announce on @VRT_Sourcefire and @kpyke. Let us know how you're using this or if you notice any bugs at