Archive for the ‘3-err’ category

Are Virtualized Systems More Or Less Secure?

May 18th, 2010

I’ve had the above question asked enough times that I felt it worthy of a blog post. While a few years back the answer may have been “less secure”, today the answer is “both”. I know, sounds like Chris being non-committal, but that answer really does most accurately describe the current state of the technology.

Virtualization Changes Everything

I’ve heard a few folks remark that virtualization is about to impact the industry the same way that the Internet did in the 90’s. To be honest, I think there is merit in that opinion. In the early 90’s most folks were running IPX, AppleTalk, NetBUI and a plethora of other protocols on closed networks. By the end of the 90’s, most folks were running IP exclusively with connectivity to the entire world. The way we did business, as well as the way we applied security, completely changed over that 10 years. Both network administration and security skills that were cutting edge in 1990 were all but useless by 1999.

Virtualization is starting to ramp up to have the same impact on the industry. Virtualization deployment requires a complete rethinking of how to apply security. Back in the 1990’s, admins who simply plugged into the Internet, without regard for how this would impact their network, got burned big time. We are lining up to see a similar outcome as folks adopt virtualization.

What Makes Virtualization Less Secure

The Achilles heel of virtualization is in the software itself. We are hoping we can trust the software to keep guest systems away from each other, as well as the host and/or hypervisor. There are two major problems with this expectation:

  1. No software is bug free
  2. Software can be misconfigured

A few years back Core Research showed they could break out of a guest and gain full control of the host OS. While a hypervisor is supposed to limit that type of exposure, we’ve certainly seen cases where even the hypervisor has been bypassed. We’ve even seen cases were software becomes exploitable only when run in a virtualized environment. These links show a small cross section of the virtualization problems that have been discovered over the last few years. Google can give you a more complete list if you are interested.

So a prudent security professional is going to be cautious of blindly trusting software to be secure. The problem is vendors do not always take this same approach. Take VMware with their ESX (soon to be ESXi) product as an example. Many of us were flabbergasted when a VMware representative announced at CanSecWest that it was theoretically impossible to attack the ESX hypervisor. When we simply assume something is unbreakable, someone more creative is going to figure out a way to punch through.

One of my biggest concerns with ESX/ESXi is that VMware has designed it to be modular (via VMSafe). On the plus side, this means that outside vendors can create products to help improve the hypervisor’s functionality and security. On the downside this dramatically increases the chances of bad code being introduced which can compromise security.

We’ve seen a great example of this in the past. Marcus Ranum created the Gauntlet firewall, which at that time was one of the most secure and kick butt security devices available. When three letter agencies wanted the best security, they turned to Gauntlet. Marcus sold Gauntlet to Network Associates (later became McAfee) who immediately started adding in features. It was not long before a steady string of vulnerabilities were being discovered, each introduced by these new “features”. From there, the product lost its security cred and slid off of the radar.

Now it is certainly possible to add features and keep things secure. The FreeBSD folks are an excellent example of how to do this correctly. To ensure security they maintain a very strict auditing process. Is it perfect? Absolutely not, but their auditing process has set the bar for secure software implementation. With any luck VMware will do similar, but I have not heard any buzz about this being the case.

Getting Your Head Straight

OK, so we can’t blindly trust virtualization software to keep attackers at bay. We can however still take precautions to help minimize the impact if the worst does occur. One of the biggest steps you can take is to carefully consider which servers get hosted, and what other guest systems are permitted to run on the same box. The security zone concept used by network architects is just as applicable here.

A security zone is simply a collection of systems that share the same relative level of risk. For example Web, name and SMTP servers are usually all located on a DMZ, because they all share similar risk from direct attack. On the internal portion of the network, desktops are usually placed in a different security zone than the servers. This is because servers have little to no access to the Internet while desktops are usually permitted to communicate directly. This places the desktops at higher risk of attack than the servers.

We can apply this same logic when implementing virtualization. A DMZ server and an internal server should not be guests on the same hardware (both CPU and disk array). Doing so could allow an attacker to create an alternate route into our network. Rather than having to pass through any firewall, NIDS, NIPS, etc. devices that has been deployed on the wire, an attacker may be able to gain access to internal resources via the virtualization software. Is it an easy attack? Not from what we have seen so far. Functional exploits have been discovered however, so why introduce unnecessary risk if we don’t have to.

By the way, these same security zone rules should be applied to your virtualized network gear. For example it is a bad idea to use the same physical switch to VLAN the DMZ and the internal network. I’ve seen a couple of clients get whacked that way.

What Makes Virtualization More Secure

Fortunately, from a security perspective, virtualization is not all bad news. In fact there are some very cool security practices you can apply in a virtualized environment that you simply cannot do without it. This was one of the reasons we started using virtualization within the Honeynet as early as 2000.

One of the biggest security issues we face today is kernel level rootkits. What makes this strain of malware so insidious is it effectively turns the operating system itself into malware. This makes detection extremely difficult, as all security checks must pass through the kernel. If the kernel itself is compromised, we can’t rely on the kernel to accurately report security information. We end up having to shutdown the system, mount the drive on a known to be clean OS, and performing our forensic checks from there. Oh course the problem with this process is that it does not scale well. If we have dozens or hundreds of servers, there simply is not enough time in a day to check them all properly.

As mentioned earlier, VMware is now permitting third party vendors access to the hypervisor API via VMSafe. This permits access to privileged state information, such as memory and network traffic, on each of the guest OSs. By plugging into the hypervisor, some extremely cool security options become possible.

For example let’s say a guest OS is attacked by a kernel level rootkit. By analyzing guest memory, the rootkit can be detected from outside of the virtual operating system. When performing the checks via the hypervisor, there is far less of a chance that a rootkit can stealth its activities and go undetected. As mentioned earlier, there is no comparable option with a non-virtualized system.

The API plug also creates new possibilities for dealing with encrypted traffic. When end to end encryption is employed (like a VPN), network based checks of the application layer are easily bypassed. Your only real option was to run agent software on the end point, so security could be implemented after the decryption process. Of course the problem here is that if the agent is attacked, all bets are off. Again, by plugging into the hypervisor we are in a better position to more safely scrutinize this data.

We are just starting to see new products that leverage the VMSafe API plug. Since all of the products are relatively new, the jury is still out on how effective they can be. Offerings run the gambit from replacing host based firewall and IDS protection to full policy enforcement. It will be interesting to see how this product niche shakes out over the next year.

Summary

So as I mentioned at the beginning of this post, virtualization has the ability to make your environment either more or less secure, depending on how you deploy it. If you simply start running everything on a single box, you are probably going to get whacked. If you extend the best practices that have been developed over the years into the virtualization realm, as well as leverage some of the new security features that are being released, you can actually create a better overall security posture.

Combining Logwatch and OSSEC – Part 4

February 18th, 2010

In my last post we installed Logwatch as well as OSSEC. It is now time to get Logwatch and OSSEC playing together in the same sandbox. In this post I’ll discuss how to get Logwatch to summarize the information being generated by OSSEC.

Deployment Options

We have two paths we can follow to set this up:

  1. Have Logwatch parse the OSSEC logs directly.
  2. Have OSSEC send its alerts to a Syslog type server, then run Logwatch on the Syslog server.

The benefit to option #1 is that we only need one system. Logwatch will be run on the system hosting the OSSEC server. The problem we are going to run into however involves the OSSEC alert file. Log entries do not get normalized. This means the format can change from entry to entry, and may even spread over multiple lines. It is going to be a real nightmare to create a Logwatch script that will filter and summarize the alert information.

If we go with option #2, we will require another box to act as our centralized logging server. In order to have the OSSEC server accept log entries from non-agent systems, it has to listen on UDP/514. This is the same port used by a centralized logging server, and you can’t have two applications share the same port (except with Windows, but socket access is extremely messy). On the plus side, the alert entries will get normalized when they are transmitted to the Syslog server so creating a Logwatch summary script will be far easier. Further, Logwatch already knows about the standard Syslog files, so we will have less customization work to do.

Finally, I mentioned in an earlier post that OSSEC is not designed to be a SIM. This is because it does not record everything, just the events that generate an alert. So we are probably going to want a centralized server anyway, and it makes sense to have it store the information being generated by OSSEC.

So if it sounds like I am steering you towards option #2, you are absolutely correct. With that said, I’m actually going to cover option #1 as it is a far more complex setup.

Dealing With Date/Time Stamps

Have a look at the main OSSEC logfile and you should see similar to the following:

[root@fubar logs]# tail -3 /var/ossec/logs/ossec.log

2010/02/18 12:32:05 ossec-rootcheck: INFO: Ending rootcheck scan.

2010/02/18 14:27:06 ossec-syscheckd: INFO: Starting syscheck scan.

2010/02/18 14:39:21 ossec-syscheckd: INFO: Ending syscheck scan.

Note the way the date/time stamp is formatted. This is different than most applications, so the first thing we will need to do is tell Logwatch how to deal with this format. We will need to create a script that we can call when needed that understands the format shown above.

Start by moving into the shared scripts directory:

cd /usr/share/logwatch/scripts/shared

Using your favorite editor, create a file named “applylongdate”:

vi applylongdate

Here is what you need inside of that file. Feel free to copy/paste from this page:

use Logwatch ‘:dates’;

my $Debug = $ENV{‘LOGWATCH_DEBUG’} || 0;

$SearchDate = TimeFilter(‘%Y/%m/%d %H:%M:%S’);

if ( $Debug > 5 ) {

print STDERR “DEBUG: Inside ApplyLongDate…\n”;

print STDERR “DEBUG: Looking For: ” . $SearchDate . “\n”;

}

while (defined($ThisLine = <STDIN>)) {

if ($ThisLine =~ m/^$SearchDate /o) {

print $ThisLine =~ s/^….\/..\/.. ..:..:.. //;

print $ThisLine ;

}

}

# vi: shiftwidth=3 syntax=perl tabstop=3 et

Once you save the file, we now need to set the proper permissions:

chmod 755 applylongdate

Configure The Log Files

Next we need to tell Logwatch where the OSSEC log files are located. Anytime you add new log files or create new services to monitor in Logwatch, you should place your changes under the /etc/logwatch directory. We are going to create two configuration files. The first will handle OSSEC messages, and the second will handle OSSEC alerts and active response changes.

Let’s start by creating the configuration file for the main OSSEC log file:

cd /etc/logwatch/conf/logfiles

vi ossec.conf

The contents of the file should be as followed:

LogFile = /var/ossec/logs/ossec.log

*ApplyLongDate =

You can now save and exit the file. Next, we will create the config file for the remaining log files:

vi ossec-alert.conf

The contents of this file should be as followed:

LogFile = /var/ossec/logs/active-responses.log

LogFile = /var/ossec/logs/alerts/alerts.log

LogFile = /var/ossec/logs/firewall/firewall.log

Once complete, save and exit. The default permissions should be acceptable for our setup.

Configuring OSSEC Services

Next, we need to define the OSSEC services and identify what we want to use as a title when reports are generated. Here’s how to create the first file:

cd /etc/logwatch/conf/services

vi ossec.conf

The contents of this file is pretty simple:

Title = “OSSEC Messages”

LogFile = ossec

Once complete you can save and exit. We need to create one more file in this directory:

vi ossec-alert.conf

The contents of this file should be:

Title = “OSSEC Alerts”

LogFile = ossec-alert

Once complete, save and exit as usual.

Parsing The Entries

Next, we need to tell Logwatch how to format the log entries within the report. We will need to create a customization script for each set of services. We are going to start by using a Logwatch supplied test script; just to make sure everything works.

Start by moving into the appropriate directory:

cd /etc/logwatch/scripts/services

Use your favorite editor to create your first script:

vi ossec

The contents of the script should be as followed:

#!/bin/bash

# This is as nice script that will show you the lines you will

# be processing and reporting on.  It will first display the

# standard environment variables and then it takes STDIN and

# dump it right back out to STDOUT.

# These are the standard environment variables.  You can define

# more in your service config file (see above).

echo “Date Range: $LOGWATCH_DATE_RANGE”

echo “Detail Level: $LOGWATCH_DETAIL_LEVEL”

echo “Temp Dir: $LOGWATCH_TEMP_DIR”

echo “Debug Level: $LOGWATCH_DEBUG”

# Now take STDIN and dump it to STDOUT

cat

Now create your second script:

vi ossec-alert

and include the exact same contents:

#!/bin/bash

# This is as nice script that will show you the lines you will

# be processing and reporting on.  It will first display the

# standard environment variables and then it takes STDIN and

# dump it right back out to STDOUT.

# These are the standard environment variables.  You can define

# more in your service config file (see above).

echo “Date Range: $LOGWATCH_DATE_RANGE”

echo “Detail Level: $LOGWATCH_DETAIL_LEVEL”

echo “Temp Dir: $LOGWATCH_TEMP_DIR”

echo “Debug Level: $LOGWATCH_DEBUG”

# Now take STDIN and dump it to STDOUT

cat

Finally, we need to set the appropriate permissions:

chmod 755 ossec*

Testing The Setup

The easiest way to test our new setup is to run the command:

logwatch | less

If you only want to see your changes, you can run a report on each service, one at a time:

logwatch –service ossec | less

logwatch –service ossec-alert | less

Further Customization

Once you get all of the above working, you can focus on getting Logwatch to filter and summarize the log entries. Logwatch is pretty flexible, and you can customize the output any way you want. One of the nice things about the above test script above is that it shows you exactly what you have to work with. So with a little regular expression magic you can summarize the entries as you deem appropriate. For some ideas, check out the files located under:

/usr/share/logwatch/scripts/services

These are the default summary scripts included with Logwatch. Specifically, have a look at the files “pam” and “sshd”. They are great examples of both a simple and a complex set of summary filters.

As you develop your scripts, pay close attention to the $LOGWATCH_DETAIL_LEVEL” variable. This will permit you to customize the output level of the report depending on how much verbosity the user is looking for. For example, while you are still in the above services directory, run the following command:

less sshd

When the first page of the file’s contents is displayed, type in:

/Detail<Enter Key>

The backslash lets us search the file for a particular text string. In this case we are searching for the word “Detail”. Once you press Enter the search will skip through the file till it finds the first instance of the text string. It will also highlight the search string. In the first match you will notice that the author assigned the variable “$Detail” to be the same as the variable $LOGWATCH_DETAIL_LEVEL”. This is to save them some typing.

Now press the backslash key again followed by the Enter key. This will jump through the file to the next instance of “Detail”. You should see:

if ($Detail >= 20) {

$Users{$User}{$Host}{$Method}++;

} else {

if ( $Host !~ /$IgnoreHost/ ) {

$Users{$User}{$Host}{“(all)”}++;

Note the author provides more information if the detail level is set to 20 (half way between low and medium) or higher. Keep jumping through the file and you will see other examples where the author leveraged this technique.

Now page down to the end of the file and you should see this statement:

if (keys %OtherList) {

print “\n**Unmatched Entries**\n”;

print “$_ : $OtherList{$_} time(s)\n” foreach keys %OtherList;

}

This section is extremely important, as it is a final catchall. Think of a firewall policy for a moment. Most of us create a final rule that says, “If I did not specifically permit a traffic pattern through, deny it”. In other words, if something unexpected happens, this is how I want you to handle it.

The above statement serves the same purpose when parsing the logfile. All of the previous “if” statements attempt to match a specific text string in the log entry in order to format it properly. This entry says “If you have not matched and printed a specific log entry yet, print it out in a section titled “**Unmatched Entries**”. This step is extremely important because without it we will never see unexpected entries. It is the unexpected entries that are probably the most important and most interesting.

Exec Summary

Both OSSEC and Logwatch are excellent complimentary tools. OSSEC excels at warning you when a known attack pattern takes place. Logwatch is a terrific tool for summarizing a time chunk of logs so humans can actually make sense of what is going on. By combining the two tools you can create a far more robust defense in-depth posture. The whole becomes greater than the sum of the parts.

Combining Logwatch and OSSEC – Part 3

February 17th, 2010

In my last two posts I discussed Logwatch and OSSEC, as well as how they can be leverage to augment your security posture. In this installment I’ll discuss how to install both of these tools.

Installing Logwatch

Logwatch is pretty easy to install. In fact, it is installed by default on many Linux distributions so you may already have a copy on your system. To check, logon as root and try running Logwatch with the “-v” switch. If you see:

[root@fubar logwatch]# logwatch -v

Logwatch 7.3.6 (released 05/19/07)

Logwatch is installed and you have a copy of the latest version. If you do not have the latest version, you can grab it from the Logwatch download page.

There are three flavors of Logwatch which can be downloaded; Binaries in RPM format, source in RPM format, or source in a Tar ball. If your system supports RPM package management, the binary RPM is your best choice. It is simple to install and RPM will automatically update the software when new versions are available.

Installing Logwatch From RPM

To install the binary version of the RPM, simply logon as root and navigate to the directory where you downloaded the RPM file. Now execute the command:

rpm -U logwatch-7.3.6-1.noarch.rpm

Don’t forget you can use the tab key to auto-complete the file name rather than having to type in the whole thing.

Installing Logwatch From Source

Installing from source is a bit more time consuming. Remember that in order to install source code you must already have a compiler (like gcc) installed on your system. Logon as root and navigate to the directory where you downloaded the Tar ball. To extract the archive, execute the command:

tar xvzf logwatch-7.3.6.tar.gz

You will see a directory structure below your current location get created and lots of files being copied in. We now need to move into the top most directory that was created:

cd logwatch-7.3.6

In order for Logwatch to run, there are a bunch of directories that need to be created on your system. These are documented in the README in the current directory. Luckily, Logwatch includes an install script that can do all the work for you. Unfortunately, the script has the wrong permissions set so it will not run by default. This is pretty easy to fix however with the chmod command:

chmod 500 install_logwatch.sh

Now we can run the script to setup our system:

./install_logwatch.sh

Don’t forget the period at the beginning of the line.

Testing Logwatch

To test your Logwatch setup, execute the command:

logwatch | less

You will see your terminal screen go blank, but that is normal. You will eventually see a Logwatch report get printed to the screen that you can navigate through using the “Page Up” and “Page Down” keys. How log it takes for the report to show up on the screen will depend on how much log information needs to get parsed. It could take a few seconds or a couple of minutes. Either way, it will give you a chance to familiarize yourself with the report format.

Installing OSSEC

As I mentioned in my last post, you have two installation options with OSSEC, local or client/server. In this post I’m going to focus on the client/server setup, as it is a bit more complex. If you are performing a local install, simply select the “local” option during the install process and skip the section on setting up a secure channel between the agent and the server.

Start With The Server

OSSEC uses Blowfish encryption to secure communication between the client and the server. Blowfish is symmetrical key based, so both sides must know what key value to use in order to communicate. The server is responsible for generating the symmetrical key, so we have to install the server software first. During the client install we will be prompted for a key value so obviously we will need to have that handy ahead of time.

Here’s a time saving tip. The key value is long and nearly impossible to remember. The easiest way to move the key value from the server system to the agent system is to use SSH. Create a secure connection to the OSSEC server, and extract the appropriate key (directions provided below). In a second terminal window, create an SSH session to the system where you will be installing the agent. When the client install prompts you for the key value, you can simply copy/paste between the two terminals.

Installing The OSSEC Server

The server software is available as a Tar ball, so you can grab a copy of the latest version from the OSSEC download page. You will then need to extract the contents of the Tar ball:

tar xvzf ossec-hids-2.3.tar.gz

Next, move into the directory structure you just created:

cd ossec-hids-2.3

OSSEC provides an install script to walk you through the process of installing the server. To start the script, type:

./install.sh

Don’t forget the period at the beginning of the command. You will now be prompted through a number of install options:

  • Language – The default is English. Change as needed.
  • Confirmation of installation – Press Enter once you have read the screen.
  • Install type – Type in “server” without the quotes and press Enter.
  • Install location – Accept the default.
  • E-mail notification – Default is yes, select if you want e-mail alerts. If you select yes, you will be prompted for a valid e-mail address and mail server.
  • Integrity check – Default is yes. Select if you want the local system periodically checked for intrusions.
  • Root kit detection – Default is yes. Good option since we need to maintain a high level of integrity on this system.
  • Active response – Default is yes. Select this option if you wish to be able to respond to events.
  • Firewall drop – Permits the OSSEC server to defend it self if a direct attack is detected.
  • White list – This will permit you to add IP addresses from which possible attacks will be ignored. Be careful with this option. If you will not have console access to the OSSEC server, it might be wise to identify one IP address that can always get in. Just ensure the source IP is a trustworthy system.
  • Enable Syslog – Default is yes. Select this option if you wish to collect logs from system that cannot run an OSSEC agent (like firewalls, switches, routers, access points, etc.).
  • Log files to be monitored – This screen identifies all of the local log files OSSEC will monitor. It is purely information, so all you can do is press Enter to move past it. If you notice one or more log files missing from the list, you can add them later to the ossec.conf file.

At this point OSSEC will access the local complier and install all needed files onto the system. Once complete, you can start the OSSEC server by executing the command:

/var/ossec/bin/ossec-control start

Defining OSSEC Agents

We are not done with the OSSEC server just yet. Next, we need to pre-define any systems that will be running the OSSEC agent (client) software. This is performed using the manage_agents command. First however, we need to do a bit of homework. Make a list of all of the systems that will be running the OSSEC agent software. For each system, you will need a descriptive name as well as that system’s IP address.

Now, execute the following from the command line:

/var/ossec/bin/manage_agents

This will produce the Agent Manager main menu. Press “A” followed by the Enter key to define your first system. Enter a descriptive name for the first system, followed by the system’s IP address. Don’t worry about the agent ID number. Simply accept the default and OSSEC will auto-assign the next available ID number. Once you confirm the information you entered, you will be returned to the Agent Manager main menu. Repeat the above process for each system that will be running an OSSEC agent.

Generating Keys

Once you have added in all of your systems, it is time to generate encryption keys. This step is also performed with the manage_agents utility. If you closed the tool after the last step, relaunch it now.

Press the “E” key followed by Enter to select the “Extract key for an agent” menu option. You will then be prompted for the ID number of the key you wish to extract. The descriptive names and IP addresses are listed with each ID number, so it should be trivial to identify which one you want. Start with the system you plan to install the agent software onto first.

OSSEC Agent Install On Linux

When installing the agent software on a Linux or UNIX client, you use the exact same Tar ball we used to install the server software. Run the same install script, but this time when you are prompted for the type of install you wish to perform, type in “agent” followed by the Enter key.

The client install has many of the same prompts as the server install. Use the info above to guide you through the process. The prompt that will vary however is that you will be asked to provide the IP address of the OSSEC server. Once complete, OSSEC will access the local complier and install all required files onto the system.

Next we need to import the Blowfish key from the OSSEC server. While still on the agent system, run the command:

/var/ossec/bin/manage_agents

When the Agent Manager menu appears, select “I” to import the Blowfish key.

When the next prompt appears, you need to manually enter the appropriate Blowfish key. Again, if you are running SSH to both systems at the same time, you can simply copy/paste between the two terminals. Make sure the key looks correct, press the Enter key, and then select “y” to confirm that the key looks correct. You will be returned to the Agent Manager menu. Select “q” in order to return to the command line.

Now we simply need to start the OSSEC agent. You can do so by executing the following command:

/var/ossec/bin/ossec-control start

You should see all of the OSSEC agent components start up, followed by a “Completed” message.

OSSEC Agent Install On Windows

OSSEC has a self-extracting executable that will permit you to install the agent software on a Windows system. Simply double click the executable to start the install process. You will be prompted to agree to the license as well as which components you wish to install. Simply follow the prompts till the OSSEC Agent Manager window appears.

The OSSEC Agent Manager window will prompt you for the IP address of the OSSEC server. It will also prompt you for the Blowfish key value to use, so extract the appropriate key on the server and enter the value in this field. Make sure you delete the prompt within this field before you paste in the Blowfish key. Otherwise communication with the server may fail.

Next, select “Manage” from the OSSEC Agent Manager menu, followed by “Start OSSEC”. You should now see the “Status:” indicator change to “Running…”.

Testing OSSEC

Once you have the server and agent software installed, started and the appropriate keys configured, it is now time to check our setup. Execute the following command on the OSSEC server:

cd /var/ossec/logs

And check out the ossec.log file:

less ossec.log

Check the log file for any errors. A common error is that OSSEC reports it cannot send e-mail. Make sure the mail server is running and that it is accepting connections. Once you are happy with the server setup, it is now time to check out the agents. Move down to the “alerts” directory:

cd alerts

And check out the alerts.log file:

less alerts.log

Specifically, you are looking for entries similar to the following:

2010 Feb 17 16:09:16 (desktop) 192.168.1.10->ossec

Rule: 501 (level 3) -> ‘New ossec agent connected.’

Src IP: (none)

User: (none)

ossec: Agent started: ‘test_system->192.168.1.10′.

You should see an entry for every system on which you installed the agent software.

More To Come

Whew! That’s more than enough for one post! In my next post I’ll get into leveraging Logwatch to parse all of the alert information being generated by OSSEC.

Combining Logwatch and OSSEC – Part 2

February 16th, 2010

In my last post I described how Logwatch could be used to simplify the log review process. In this post we’ll look at OSSEC and what it brings to the table.

What Is OSSEC?

OSSEC, short for “Open Source SECurity”, is a host based intrusion detection system (HIDS). In other words, it is designed to detect attacks or policy violations if and when they occur. While it does not have the ability to protect against unknown or 0-Day attacks (that would be host based intrusion prevention), it does include a wide range of tools which can help you identify an intrusion when it occurs, as well as the extent of the damage that has been caused.

Supported Platforms

To take advantage of all of the features OSSEC has to offer, you have to run an agent on the system being protected. OSSEC agents can run on Windows, Mac OS X, Linux, and a wide range of UNIX systems. If you are just interested in the log analysis portion however, an even wider range of systems can be supported. This includes hardware from both Cisco and Juniper. A number of specific products are also supported like Checkpoint firewalls, Symantec Anti-Virus, Snort, Squid, and Arpwatch, just to name a few.

When you install OSSEC you have two configuration options, local or client/server. A local install is used when you need to run everything on a single system. The client/server installation lets you run a distributed environment protecting multiple systems at the same time. While most deployments are client/server based, if you want to give OSSEC a spin you can easily run everything on a single test system using a local install.

Log Analysis

OSSEC includes a Log-based Intrusion Detection System (LIDS). This has the ability to review log files in near real time, while scrutinizing them for known attack patterns. When a log is generated on a protected system, the agent takes care of securely transmitting the log (Blowfish encryption using a pre-shared secret) back to the server. The server then takes care of performing the analysis.

Most log analysis tools process their rules in a linear format. By that I mean if we have 500 rules, rule one is checked, then rule two, then rule three and so on till a match is found or we reach the end of the rule set.  OSSEC works a bit differently as it implements a hieratical structure to the rules. Log entries are first classified and then checked only against whichever rules are appropriate. The result is that rather than needing to process all 500 rules, most events will get checked against 10 rules or less. This dramatically reduces the amount of overhead required to process the rule set.

Integrity Checking

OSSEC includes a tool called Syscheck for performing file and directory integrity checking. If you are running a Windows agent, you can also include specific keys within the Windows registry to be monitored as well. File changes can be detected using both MD-5 and SHA-1 hash algorithms. The system is extremely customizable. You can include or exclude single files, or entire directory structures. You can even set a flag to detect new file creation.

The agent software is designed to use a minimal amount of CPU during the integrity check. While this means the check will take longer, it also helps to minimize the performance hit to the system. Hash information is transmitted back to the server. The server then takes care of performing the hash comparison to see if any of the system’s critical files have been changed. The server also stores a copy of the integrity check policy, so that if policy changes are made on the agent, they can be detected and reported as well.

Anomaly detection

OSSEC goes far beyond log checking to verify system integrity. Usage policies can be centrally managed from the server, and then pushed out to the appropriate agents. For example you could define a policy regarding which Windows applications are acceptable (Office, Firefox, etc.) and which ones are not (IM client, Skype, etc.). You can even define acceptable configuration options like verifying that NT hashes are being used for password stored but not LanMan hashes.

OSSEC includes a number of other goodies in order to help verify a system’s integrity. For example OSSEC has the ability to execute commands from the agent and monitor the output that gets generated. For example you could have the Linux agent execute the “df” command at regular intervals and generate an alert if disk usage exceeds 90%. A Windows example may be to have OSSEC generate an alert whenever file information is written to the alternate data streams area of NTFS.

Active Response

Finally, OSSEC includes the ability to respond when suspicious activity is detected. Responses can be generated from the server or the agent, which ever you specify. Responses can be as benign as generating an e-mail alert, to being as proactive as blocking a remote IP address for a limited amount of time. There are a number of included active response scripts you can draw on, or you can easily write your own.

Secure Architecture

The OSSEC authors have gone to great lengths to secure all of the components within the product. Tasks such as integrity checking are performed on the server, rather than the agent, so the trustworthiness of the hashes cannot be compromised during an attack. Processes are run with the lowest level of permissions possible, and different accounts are used to run each OSSEC component. This means that a compromise of a single application within OSSEC will not immediately lead to a compromise of the full package. Further, most components are run within a chrooted jail so their access to the system is even further restricted.

Final Words

While OSSEC is a powerful tool, it is important to remember that it is a HIDS and not a log management solution. OSSEC can review log entries looking for suspicious patterns, but it will only save alert information. So while OSSEC will not replace your Security Information Management (SIM) solution, it can most certainly augment it. You can easily setup OSSEC to forward all alerts it generates to a central logging server.

While OSSEC is open source software, Trend Micro is primarily developing it. If you need commercial support, you can purchase a support contract through them at a reasonable fee.

More To Come

In my next installment we’ll look at installing OSSEC and Logwatch. After that, we’ll move into integrating the two together.

Combining Logwatch and OSSEC

February 15th, 2010

I recently had a student ask me a question regarding the integration of Logwatch with OSSEC. I felt like this was a complex and yet cool enough idea that it warranted a series of posts to cover it in full. So over the next few days I’ll talk about each of these tools, how to integrate them together, as well as what additional security visibility can be gained once the process is complete.

What Is Logwatch?

Logwatch is an excellent open source tool for generating daily human readable log reports. Log entries tend to fall into one of three categories:

  • Stuff you know is evil
  • Stuff you know is normal and can be safely ignored
  • Everything else

It is that “everything else” category where Logwatch really shines. For the stuff we know is evil, we will setup some form of alerting system. For example we may write an alert signature that warns the security analyst when an account is being brute forced. But what about the attacks we don’t know about or are not sure what they look like? This would be a clear example of that “everything else” category. The traffic is not normal, but we have not seen it before to have a signature waiting to generate an alert. Since we will be unable to catch the attack in real time, we will need to catch it during a daily log review.

Of course the problem with doing daily log reviews is that it is tedious and time consuming. I mean let’s be honest, who really wants to spend their day reviewing one million plus log entries? Even if you did, are you sure you would actually catch the out of the ordinary traffic?

How It Works

What Logwatch does very well is permit you to reorganize your data into a format that is easier for humans to follow. Its real strength is that it permits you to move the stuff you understand out of the way (normal or evil), so that the unexpected log entries stand out like a sore thumb. In other words, Logwatch lets you summarize your log entries so the unusual stuff is easier to spot.

What I really love about Logwatch is that you don’t lose anything. Many log review tools will only show you the stuff that has been pre-defined as being evil. The problem they all share is that when something evil but unexpected happens, it flies right under the wire. Because Logwatch lets you see everything, you no longer miss the unexpected.

Logwatch In Action

Lets discuss how Logwatch works using the SSH server service as an example. The scripts to deal with SSH have already been defined within Logwatch, so you do not need to do any tweaking to receive the features we are going to discuss.

When reviewing a log file, the first thing Logwatch does is reorganize log entries based on their message types. For example all Successful SSH logons are grouped together, as well as too many logon failures, refused connections, locked accounts, accounts without a proper shell, protocol mis-matches, etc. etc. etc. Once all the SSH messages are grouped by their type, the data is then summarized to reduce the amount of information being reported.

For example, the default is to summarize failed logon attempts by account and source IP. So a typical failed logon report section might look like this:

Failed logins from these:

bsmith/password from 1.2.3.4: 637 time(s)

jsmith/password from 1.2.3.5: 2 time(s)

So rather than having to review 639 log entries reporting a bad logon attempt, we have all the pertinent information summarized into three lines (if you include the title). Continue this process for all of the other SSH messages, and we have dramatically reduced the amount of time required to review our logs.

But what if something happens that Logwatch is not pre-programmed to recognize? When an unexpected log entry is found, Logwatch adds a section to the end of the service report called “Unmatched Entries”. So if we see this title in the SSH server section, we know some event has occurred that is either abnormal or unexpected for the SSH service. This could very well be some form of attack that we are not aware is making the rounds.

By focusing in on the unmatched entries section, we can quickly identify unexpected activity. As I stated earlier, this is really the main goal of doing daily log reviews. To find the stuff we don’t expect which will sneak past our alerting system. Logwatch makes this process as quick and as painless as possible.

Feature Summary

In the above example I talked about doing daily log reviews, but to be honest Logwatch is highly customizable. You can specify any range you wish to use down to an interval of one second. For example let’s say I’m investigating an intrusion rather than performing a daily log review. I could specify a range such as “2010/02/14 17:05:00 for that hour” to focus right in on the information that interest me. I can also focus in on one specific log file or service.

The detail level of the report is also customizable. Typically when you deal with security you get in the habit of always wanting the highest detail level of reporting. To be honest, with Logwatch a high level of detail is probably more than you will ever need. Personally I typically stick with “med” for medium and that works out nicely. You can also specify the reporting level as “low” or “high” or use a numeric range of 0-10 for a higher level of granularity (low =0, med=5, high=10).

Logwatch can be run automatically or as a manual process. Typically you will want to set it up to run automatically each day and summarize one day’s worth of log entries. If you ever need to expand or focus the report, you can always run Logwatch from the command line while specifying exactly what you want to see. You can then use the “–save” option to specify a report name and directory location for storage.

More To Come

The above should give you a good idea as to the features Logwatch can bring to the table. In the next post I’ll discuss OSSEC in the same level of detail. After that, I’ll get into how to install each tool as well as how to integrate them together.

Day 2 Keynote

January 12th, 2010

Thanks to all who came out to the Encryption/DLP summit. Here are the slides from my keynote on day 2.

encryption-dlp-keynote

ICMPv6 Challenge – Answers

December 13th, 2009

The challenge was: “Write a tcpdump/windump filter that will capture ICMPv6 Multicast Listener packets.” I have an extensive write up on what makes the answer so complex. If you know IPv6 and just want the answer, skip to the end.

First, Some Background

Steinar made some comments to the previous posts and was 100% on track. If you read them and thought “Wow, that sounds really messy”, you understand the scope of the problem as well. :)

Protocol Vs. Next Header Field

With IPv4 we had the options field. This could cause the IP header to grow from 20 bytes to as large as 60 bytes in size. With IPv6, there is no longer an options field and the header is fixed at 40 bytes in size. When options are required, we use extension headers to identify them. This throws an interesting curve ball at us because with IPv4 the protocol field (byte 9) would (almost) always identify the upper level transport (TCP, UDP, etc.). With IPv6 the next header field (byte 6) might identify the upper layer transport, or it might identify an extension header which will include some number of options.

Here’s a list of some IPv6 extension headers you might run into, as well as the RFCs that define them:

Option # Option Description RFC
0 Hop-by-Hop 2460
6 TCP 793
17 UDP 768
43 Routing 5095
44 Fragmentation 2460
50 ESP 4303
51 AH 4302
58 ICMPv6 4443
59 No next header 2460
60 Destination options 2460
135 Mobility 3775

IPv6 does not limit the number of extension headers you can use in a single packet.There is however a published “recommended order” as to how the headers should be laid out. The order is:

  • IPv6 Header
  • Hop-by-Hop Options
  • Routing Header
  • Fragment Header
  • AH
  • ESP
  • Destination Options
  • Mobility Header
  • TCP/UDP/ICMPv6

Note this list is “recommended” but not mandatory. An IPv6 host must be able to process the headers in what ever order they were received. This means you will probably find vendors following this list but not attackers. I’ve personally seen devices start acting really odd when you mess with the header order. In fact I’ve run across quite a bit of “IPv6 compatible code” which can’t deal if the preferred order is not used.

Chasing The Protocol Header

So with IPv6 we can have multiple headers behind the IPv6 header. If this sounds like a new concept, it is actually not. In fact you’ve probably worked with it already. When you deploy IPSec the two possible security protocols are ESP and AH. These were actually borrowed from IPv6 and massaged to work on IPv4. Both AH and ESP include a next header field to identify what type of packet they are protecting.This is referred to as protocol chaining, as you effectively have multiple headers sitting behind the layer 3 protocol header.

So to figure out what upper level transport (TCP, UDP, etc.) is being used, you may have to search through multiple headers before you find the answer. This is referred to as “chasing the header“, and tcpdump/Windump give us a filter option to perform this task. You may be fimiliar with the proto filter. In the IPv4 world, if I say:

ip proto tcp

That filter reads “check byte 9 of the IPv4 header and if the value is equal to 6 (protocol value for TCP), match on the packet”. This filter is not as effective in the IPv6 world of course because byte 6 of the IPv6 header might identify the upper layer transport, or it might just identify an optional extension header that is being used. To solve this problem, the protochain filter was introduced. Writing:

ip6 protochain tcp

Reads as “Check byte 6 of the IPv6 header to see if the value is equal to 6. If instead you find a value which identifies an optional extension header, check the extension header’s next header field for a value of 6. If you find more optional extension headers, keep repeating the last test till you find the last extension header”.

Pretty simple to write in English, but this is a nightmare to implement in code. Most optional extension headers are variable in length which just adds to the complexity. I’ve done some testing with Scapy and you can actually see the difference in performance when protochain gets invoked. In fact you could probably do a pretty good job of DoSing an IDS/IPS by forcing it to process a lot of useless extension headers.

Writing our filter

So our first problem in writing the challenge filter is that the ICMPv6 header may not appear right after the IPv6 header. We have to watch out for optional extension headers. In fact RFC 2710 states: “All MLD messages described in this document are sent with a link-local IPv6 Source Address, an IPv6 Hop Limit of 1, and an IPv6 Router Alert option [RTR-ALERT] in a Hop-by-Hop Options header.” This means our multicast listener packet is required to have a Hop-by-Hop extension header with the Router Alert option set. With this in mind, our first check should be:

ip6 protochain icmp6

To ensure we are only looking at ICMPv6 packets. Now it is just a matter of checking to see if the type field (byte 0) is set to 130 (Multicast Listener Query) or 131 (Multicast Listener Report).This brings us to our second problem however. In the IPv4 world I can do a:

icmp[0]= <type value of interest>

If I try this with icmp6 I get:

[root@fubar ~]# tcpdump -nn icmp6[0]=130
tcpdump: IPv6 upper-layer protocol is not supported by proto[x]

In other words, I can’t use offsets with icmp6 to search for specific values. Windump and tcpdump are advertised as IPv6 compatible, but don’t expect to get all the same functionality you have with IPv4. YUCK!

So what do we do? We’ll have to fall back on referencing the value from an ip6 offset. In other words, we’ll have to measure through the IPv6 header, through the required Hop-by-Hop header, and into the ICMPv6 header to see if the type field is set to 130 or 131. Some things to take into consideration:

  • IPv6 header is fixed at 40 bytes in size
  • Hop-by-Hop header is variable, but 4 bytes with Router Alert set
  • The type field is byte 0 within the ICMPv6 header

So here is what we end up with:

ip6 protochain icmp6 and (ip6[44]=130 or ip6[44]=131)

Whew! We finally got it! Or did we?

Q: What happens if the packet has additional extension headers?

A: Our filter will not work.

Q: What if the Hop-by-Hop header has more options set than Router Alert?

A: Our filter will not work.

Q: Can we fix the above two problems?

A: Not till tcpdump/Windump filtering adds IF/THEN loop support.

So if we want to capture normal ML traffic, the above filter will work fine. If however we want to insure we catch attacker trickiness as well, the filter is not going to fly.

What if we try something like this:

tcpdump -nn -s 1500 -x ip6 protochain icmp6 | grep -i multicast > multicast.txt

and then just use Wireshark’s text2cap tool to convert it to Libpcap format? The problem here is we will only get the header info. Grep will match the summary line which contains the word “Multicast” but then skip all the Hex below it which is the actual contents of the packet.

So the final answer is: “Can’t get theya from haya” ;)

So what if you really need to be able to see this traffic? Until support for IPv6 matures, the only 100% method is to grab all ICMPv6 traffic and then manually sort through it.

At least that’s my view on this. If anyone can actually come up with a 100% working solution, I would love to hear it.

ICMPv6 Challenge – Hints

December 9th, 2009

OK, here’s a hint to point you in the right direction.

The challenge was: “Write a tcpdump/windump filter that will capture ICMPv6 Multicast Listener packets.”

Sounds easy, right?

With a little help from Google you’ll find that the “type” for Multicast listener is 130, and the ICMPv6 type field is the first byte in the header. So this should be as easy as:

tcpdump -nn -p -v -s 0 icmp6[0]=130

however if you run the command you’ll get back:

tcpdump: IPv6 upper-layer protocol is not supported by proto[x]

In other words, you can use “icmp6″ to see all ICMPv6 packets, but you can’t use it to filter on any of the ICMPv6 header fields.

So we need a “Plan B”. Figure out plan B and you’ve solved the challenge. :)

ICMPv6 Challenge

December 4th, 2009

Building on the IPv6 challenge from last time, I have a new one for you: Write a tcpdump/windump filter which will capture ICMPv6 Multicast Listener packets.

That’s it! Pretty easy, right? ;)

Weekend Challenge – Answers

December 3rd, 2009

Well its now Thursday so I figured its time to post the answers to last weekend’s challenge. ;)

First, why should you even care about IPv6 if you have not started deploying it? I felt much the same way till I found IPv6 being used as a covert communication channel within a client’s network. The data was then being pushed out to the Internet via Teredo. If you are not familiar with the technique, Scott Hogg has some excellent posts on the topic.

So even if you are not currently using IPv6, it pays to start cutting the cure on the technology as well as watching for it on your local network.

So to review, the challenge was:

Write a tcpdump or Windump filter that will capture all traffic with a source IPv6 address of 2001:db8::10 through 2001:db8::20.

There are a couple of caveats with writing this filter. The first few I covered in the last post. The final one, which I knew but never really thought was a problem till I started working with IPv6 pretty heavily, is that tcpdump/Windump will only let you use 1, 2 or 4 byte masks. So while we would love to solve this with an initial filter statement of “ip6[8:14]=”, we can’t because we’re limited to 4 bytes. There is in fact a way to get around this, but I’ll come back to it.

So here’s the filter I’ve been working with:

(ip6[8:4]=0x20010db8 and ip6[12:4]=0 and ip6[16:4]=0 and (ip6[20:4]>=0×0010 and ip6[20:4]<=0050))

Bit long, but it works. Elizabeth came up with a solution that is far more elegant than my own:

src net 2001:db8::/122 and ip6[23] >= 0×10 && ip6[23] <= 0×20

So by starting with the Libpcap format, she’s able to combine my first three statements into one. Not to be a size queen, but that makes her solution is much shorter than mine. In this case that’s a good thing. :)

That’s about it. I’ll post another IPv6 type challenge tomorrow.