Sunday, November 23, 2008

Time for a change

As most of you probably know, I've operated my own security consulting business for the past few years. What is less widely known is that it was a part time affair, as I kept a full time job working for a US nuclear physics research lab. I was very happy with the way things were going, but sometimes you just get an offer that's too good to refuse...

That's pretty much how I felt when I started talking to Richard Bejtlich about coming over to GE to help them build an enterprise-wide CSIRT. This is an exceptional chance to help create an incident response capability that could have a very real effect on the security posture of one of the largest companies in the world, and who could turn that down? To top it off, I know some of the other team members, and I can honestly say that they're a top-notch group of people. And in my book, interesting work combined with a high powered team of experts equals an opportunity I just had to take.

So starting tomorrow, I'll be an Information Security Incident Handler for GE. I promise this won't turn into a GE blog, though. You'll still see the same quality technical articles you've come to expect. That is, if my new boss will unshackle me from the oars every now and then. Heh.

Monday, November 03, 2008

Detecting outgoing connections from sensitive networks with Bro

As I mentioned in my last post, I've been playing with the Bro IDS. I wanted to take a stab at creating my own policy, just to see what it's like to program for Bro. It turned out to be surprisingly easy.

I started with the following policy statement: There are certain hosts and subnets on my site which should never initiate connections to the Internet. Given that, I want to be notified whenever these forbidden connections happen. To accomplish this, I created restricted-outgoing.bro.

To use this sample, copy into your $BRO_DIR/site directory, and add "@load restricted-outgoing" to your startup policy (the mybro.bro script if you're following my previous example).



##
## Detect unexpected outgoing traffic from restricted subnets
##
@load restricted-outgoing

Now the code is loaded and running, but it must be configured according to your site's individual list of restricted hosts and subnets. Following the above lines, you can add something like:

redef RestrictedOutgoing::restricted_outgoing_networks = {
192.168.4.0/24, # restricted subnet
10.0.0.0/8, # restricted subnet
192.168.9.43/32, # individual host
};

If you run Bro now, you should start seeing lines like the following in your $BRO_DIR/logs/alarms.log file:

1225743661.858791 UnexpectedOutgoingUDPConnection
x.x.x.x/netbios-ns > y.y.y.y/netbios-ns : Restricted
Outgoing UDP Connection

1225743661.858791 UnexpectedOutgoingTCPConnection
x.x.x.x/netbios-ns > y.y.y.y/netbios-ns : Restricted
Outgoing TCP Connection

Similar entries will also show up in your $BRO_DIR/logs/restricted-outgoing.file.

This script considers a connection to be a tuple composed of the following values: (src_ip, dst_ip, dst_port). When it alerts, that connection is placed on a temporary ignore list to suppress further alerts, and a per-connection timer starts counting down. Additional identical connections reset the timer. When the counter finally reaches 0, the connection is removed from the ignore list, so you'll receive another alert next time it happens. The default value for this timer is 60 seconds, but you can change it by using the following code:

redef RestrictedOutgoing::restricted_connection_timeout = 120 secs;

Even though your policy may state that outgoing connections are not allowed from these sources, it may be the case that you have certain exceptions. For example, Microsoft Update servers are useful for Windows systems. There are three ways to create exceptions for this module:

First, you can define a list of hosts that any of the restricted nets is allowed to access:

redef RestrictedOutgoing::allowed_outgoing_dsts = {
72.246.0.0/15, # Akamai, usually updates
};

Second, you can list services which particular subnets or hosts are allowed to contact:

redef RestrictedOutgoing::allowed_outgoing_network_service_pairs = {
[192.168.4.7/32, 25/tcp], # SMTP server
[192.168.4.8/32, 80/tcp], # Web proxy
[192.168.4.9/32, 53/udp], # DNS server
[10.0.0.0/8, 123/udp], # NTP
};

Finally, you can list specific pairs of hosts which are allowed to communicate:

redef RestrictedOutgoing::allowed_outgoing_dst_pairs = {
[myhost.myorg.org, www.google.com],
[192.168.4.23, www.business-partner.com],
};

Note that this is the only one of the three options that allow you specify individual IPs without CIDR block notation, or to use hostnames. The hostnames are especially useful, as Bro automatically knows about all the different IPs that the hostnames resolve to, so the "www.google.com" above would match any of the IPs returned by DNS.

Overall, I found the Bro language pretty easy to learn, and very well suited for the types of things a security analyst typically wants to look for. I was able to bang out a rough draft of this policy script on my second day working with Bro, and I refined it a bit more on the third day. Of course, I'm sure an actual Bro expert could tell me all sorts of things I did wrong. If you're that Bro expert, please leave a comment below!

Update 2008-11-06 14:45 I have uploaded a new version of the code with some additional functionality. Check the comments below for details. And thanks to Seth for his help!

Getting started with Bro

Lately, I've been playing with Bro, a very cool policy-based IDS. I say "policy-based" because, unlike Snort, Bro doesn't rely on a database of signatures in order to detect suspicious traffic. Rather, Bro breaks things down into different types of network events, and Bro analysts write scripts to process these events based on their particular detection policies and emit alarms.

At first, I was pretty puzzled about how to get started. The Bro website has some quick start docs, but they direct you to use the "brolite" configuration (a kind of simplified, out-of-the-box configuration). The bad news for that, however, is two-fold. First, the configuration is listed as deprecated in the files that come with the source tarball, and second, the brolite installation process doesn't work right under Linux.

So for the record, here's what you need to get started with Bro. (Thanks to Bro Guru Scott Campbell for helping me out with this):


  1. # ./configure --prefix=/usr/local/bro
  2. # make && make install
  3. # cp /usr/local/bro/share/bro/mt.bro /usr/local/bro/site/mybro.bro

After that, create the file runbro.sh:

#!/bin/sh
export BROPATH=/usr/local/bro/policy: \
/usr/local/bro/policy/sigs:/usr/local/bro/site

./bro -i eth1 --use-binpac -W mybro.bro
Now you can just run runbro.sh and it'll do the right thing. The new mybro.bro file will be a very stripped down default set of policies. It won't do that much, but you can then add to it as you see fit. You can find more details about this in the Bro User Manual and Bro Reference Manual.

By the way, this example uses the --use-binpac option to enable some new-style compiled binary detectors. This caused Bro to crash frequently on my RHEL testbed, so if the same happens to you, you might need to leave that option out.

Wednesday, September 10, 2008

Catastrophic consequences of running JavaScript

Wow, I had no idea simply running JavaScript could be this bad. I'm really happy now to be running the excellent NoScript Firefox extension.

First, take a look at HasTheLargeHadronColliderDestroyedTheWordYet.com. DO NOT VISIT THIS PAGE WITH A JAVASCRIPT-ENABLED BROWSER!

Notice that the page displays a simple "Nope", indicating that the world has not yet ended. Whew!

Next, view the source for that page. You'll see the following snippet of code:


<script type="text/javascript">
if (!(typeof worldHasEnded == "undefined")) {
document.write("YUP.");
} else {
document.write("NOPE.");
}
</script>
<noscript>NOPE.</noscript>


Let me walk you through that code... First, if you have JavaScript enabled, everything between <script> and </script> is executed, which comes out to be a single if statement, where one of the possible outcomes is that the world, in fact, has been destroyed.

On the other hand, if your browser doesn't support JavaScript, the page simply renders whatever is inside the <noscript> stanza, which always evaluates to "NOPE."

In other words, with JavaScript enabled, there's a small (but finite) chance that the world could end! However, with no JavaScript, there's zero chance. Therefore, JavaScript is demonstrably dangerous! The risk far outweighs any temporary benefit we could gain from this technology!

Do not tempt fate! Disable JavaScript everywhere IMMEDIATELY! You have been warned!

Monday, September 08, 2008

How those Internets work

If you're a lot of analysts, you probably have a very good grasp of how networks work at the LAN, WAN and maybe even MAN level. You also probably know that "the Internet" is really just a collection of independent networks that have mutually agreed to talk to each other, but you're not exactly sure how all that works.

If that sounds like you, I highly recommend Rudolph van der Berg's article How the 'Net works: an introduction to peering and transit. It's a great introduction to peering and transit agreements, which goes into detail about how traffic routes from one network to another without using a lot of technical jargon. I particularly like the discussion of the economics of choosing peering vs. transiting.

Great article. I have to say, it's one of the most informative networking articles I've read in a while.

Monday, July 28, 2008

Chinese Hacker Podcast

The good folks over at The Dark Visitor have just completed their first podcast. These guys are a great resource for those of us who don't speak Chinese, and if you're not reading and listening, you probably should be.

Thursday, June 19, 2008

Integrating domain reputation search into Firefox 3

This happens to me every day. I find a domain name somewhere, usually through my NSM work, and I wonder, "Is this domain known to be malicious?" Now, I don't personally know every domain on the Internet, but I've had some success using McAffee's SiteAdvisor. You feed it a domain name, and it'll tell you not only if it thinks it's suspicious, but also whether or not it offers any sort of downloads, what other sites it's most closely associated with, and what it's users have to say about it (if anything).

Pretty good stuff, but I'm so lazy. Opening a new tab and typing in the SiteAdvisor URL is just sooo hard! So I decided to add it to my list of search plugins, so I can use the integrated search bar instead. Here's how to do it.

  1. Find your searchplugins directory. For a typical Unix system, this is ~/.mozilla/firefox/XXXXXXXX.default/searchplugins (where the XXXXXXXX is a random string)
  2. Create a file in this directory called siteadvisor.xml with the contents below.
  3. Restart Firefox.


There you go! Three simple steps, and now "Siteadvisor" should be listed when you drop down the search menu.

<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" 
xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>Siteadvisor</os:ShortName>
<os:Description>Search McAffee Siteadvisor</os:Description>
<os:InputEncoding>UTF-8</os:InputEncoding>
<os:Url type="text/html"
method="GET" template="http://siteadvisor.com/lookup/?q={searchTerms}">
</os:Url>
</SearchPlugin>


Now, the question of the day: What other sites do you use to easily check a domain's reputation? Leave a comment and let us know!

Monday, June 16, 2008

OSSEC Project Acquired

Congratulations to Daniel Cid, who's OSSEC project has just been acquired. Now that Daniel will be working on the project full time, I think we can look forward to some great things!