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. :-)