Thursday, October 30, 2008

White Paper on the MS08-067 vulnerability and the associated malware

Matt Olney, Alain Zidouemba and Lurene Grenier of the Sourcefire VRT have collated their analysis of the DCE/RPC vulnerability announced in Microsoft Security Bulletin MS08-067. A white paper that discusses this issue is now available on snort.org at the following address:

http://www.snort.org/vrt/docs/white_papers/

As always, we do not require any kind of form to be filled in, nor do we ask for a login to get our white papers. Enjoy.

Tuesday, October 28, 2008

Update on Snort and ClamAV for ms08-067

There's been a lot of action on the MS08-067 front over the weekend, so we thought we'd bring you up to date on the bug in general, and how Snort and ClamAV are providing specific detection. Interestingly, things are rolling out about the way we expected them to. We happened to be visiting a Snort class here in Columbia to field some questions last Thursday, and one of the students asked about how long it takes to move from binary patching to a POC. Our answer was as little as two hours. As it turns out, one private research organization reported EIP a little over two hours after patching for MS08-67 was released. That patch window is getting pretty small.

Snort Update

Of course, when you're dealing with 0-day, the patch window is an invalid concept. The VRT just finished up working through the actual pre-patch attack worm. We're pretty pleased with the outcome of our testing. After doing some reverse engineering and writing a quick DLL loader, Alain Zidouemba and Lurene Grenier were able to trigger the original, 0day attack in a controlled environment. We were able to get a pcap of the attack, and here are the test results from an all-rules load of Snort against that pcap:

[0-Day attack]

Alerts:
122:3:0 (portscan) TCP Portsweep Alerts: 1
1:7218:8 NETBIOS SMB srvsvc NetrPathCanonicalize WriteAndX little endian overflow attempt Alerts: 3
3:14809:1 NETBIOS SMB srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 3
1:7238:8 NETBIOS SMB srvsvc NetrPathCanonicalize little endian overflow attempt Alerts: 3
1:1394:8 SHELLCODE x86 NOOP Alerts: 42
122:1:0 (portscan) TCP Portscan Alerts: 5
3:14783:1 NETBIOS DCERPC NCACN-IP-TCP srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 3

We're happy to see that our newly published rules: SID 14809 and SID 14783. But there are a couple of more important things to notice here. We see plenty of evidence of "bad", with 42 alerts from the x86 NOOP rule from SHELLCODE. This would certainly give a skilled analyst a shot of detecting the 0-day attack. But the most important alerts are SID 7218 and SID 7238. These are from our detection set for MS06-040, a vulnerability from the same function as MS08-067. Because the attackers chose to use the same string that provided the overflow to also deliver the payload, they tripped the overlly long string check in our MS06-040 detection. So customers who had protection enabled from either SID 1394 or SID 7238 and SID 7218 had 0-day protection from this attack.

After the release of the binary patch, it can take a while to make a reliable exploit, and it wasn't until this weekend that public exploits began to appear. The first PoC up on Milw0rm was interesting. From a quick look at the source code, and in looking at how it behaves against our sensors, we actually believe that this POC is triggering the ms06-040 vulnerability, as opposed to the MS08-067 one. The PoC was actually up on Thursday, 10/23, and the first Milw0rm remote entry didn't show up until the 26th. Here is the testing output from the PoC and the

Remote:
[Milw0rm PoC]

Alerts:
3:14817:1 NETBIOS SMB srvsvc NetrpPathCononicalize unicode little endian path cononicalization stack overflow attempt Alerts: 1
1:1923:9 RPC portmap proxy attempt UDP Alerts: 2
1:7224:8 NETBIOS SMB-DS srvsvc NetrPathCanonicalize unicode little endian overflow attempt Alerts: 1
3:14783:1 NETBIOS DCERPC NCACN-IP-TCP srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 1

[Milw0rm Remote]

Alerts:
3:14817:1 NETBIOS SMB srvsvc NetrpPathCononicalize unicode little endian path cononicalization stack overflow attempt Alerts: 1
1:7209:8 NETBIOS SMB srvsvc NetrPathCanonicalize unicode little endian overflow attempt Alerts: 1
3:14783:1 NETBIOS DCERPC NCACN-IP-TCP srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 1

Again, we detect both on the MS06-040 rules and our newly provided MS08-067 rules. Because the attackers chose to put payload in the same string as the attack, they trigger the overflow check in our prior MS06-040 rules. This won't always be the case, as payload can be placed outside the stub, but we would still alert on the "path cononicalization stack overflow attempt" rules.

We've also verified coverage against Core Security Technologies' Core Impact module that exploits this vulnerability. Not surprisingly, this was a reliable attack mechanism against machines that are shown by Microsoft's documentation to be vulnerable to this attack. Again, it triggers prior coverage on our MS06-040 rules:

[Core Impact]

Alerts:
1:1390:6 SHELLCODE x86 inc ebx NOOP Alerts: 2
3:14809:1 NETBIOS SMB srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 2
1:7235:8 NETBIOS SMB-DS srvsvc NetrPathCanonicalize little endian overflow attempt Alerts: 2
1:1923:9 RPC portmap proxy attempt UDP Alerts: 10
1:648:9 SHELLCODE x86 NOOP Alerts: 2
3:14783:1 NETBIOS DCERPC NCACN-IP-TCP srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 2

Because this is a well formed attack, we see a couple of additional things in this detection. The RPC portmap alert is triggered as the attack determines the attack vectors available to it. We also see indications of NOP sleds through SID 1390 and SID 648. Depending on how the attacker chooses to lay out the attack, NOP sleds can be an important component of attack detection, particularly in 0-day cases. I would strongly recommend that you leave active as many SHELLCODE rules as you can, to give your analysts a chance in 0-day cases. In this case though, we have solid detection, both in the form of SID 7235, our MS06-040 detection, and our MS08-67 specific set of detection.

Finally, we just finished up coverage testing for HD Moore's ms08-067 module for Metasploit. There is a lot of interesting things going on here, which we'll be covering in an upcoming white paper release. But for now, here is the Snort detection output:

[Metasploit]

Alerts:
3:14793:1 NETBIOS SMB srvsvc NetrpPathCononicalize WriteAndX little endian path cononicalization stack overflow attempt Alerts: 1
1:7250:8 NETBIOS SMB-DS srvsvc NetrPathCanonicalize WriteAndX little endian overflow attempt Alerts: 2
3:14783:1 NETBIOS DCERPC NCACN-IP-TCP srvsvc NetrpPathCononicalize little endian path cononicalization stack overflow attempt Alerts: 1

Again...ms06-040 coverage plus our update coverage. Note the absence of other identifying traffic (shellcode, scanning, etc...) without targeted coverage, you would miss this attack.

As a final take away, notice that in three attacks, we have several different alerts. Because of the time Brian Caswell and the VRT have put towards handling a variety of NetBIOS attack vectors, Snort is able to provide broad, comprehensive detection for attacks. This leads to a larger number of rules to provide this coverage, so I strongly encourage you to upgrade to at least Snort 2.8.2, when we introduced the binary tree structure to the rule parsing process. This provides a significant performance increase to the large, but well formed for a binary tree, NetBIOS ruleset.

ClamAV Update (Courtesy of Alain Zidouemba)

A number of files by the name of n[x].exe (where [x] denotes a integer number) have been observed to be a payload as a result of the MS08-067 vulnerability. The Trojans are usually 388KB in size. Once executed, n[x] starts off by trying to ping the server 202.108.22.44. A whois of this IP address reveals that the machine is on a Chinese domain.
n[x].exe then drops the file %SYSTEMROOT%\system32\wbem\sysmgr.dll on the hard drive and registers the service “System Maintenance Service” that points to sysmgr.dll.
The following registry keys are created as well:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sysmgr\ParametersServicedll = %SystemDir%\wbem\sysmgr.dllServicemain = servicemainfunc

The file attempts to ping 64.233.189.147 which is a computer part of the google.com domain. The Trojan very likely pings google.com to verify network connectivity. The assembly code for sysmgr.dll reveals that the Trojan then checks the registry for the presence of the following registry keys:

HKLM\Software\Jiangmin
HKLM\Software\KasperskyLab
HKLM\Software\Kingsoft
HKLM\Software\Symantec\PatchInst\NIS
HKLM\Software\Microsoft\OneCare Protection
HKLM\Software\rising
HKLM\Software\TrendMicro

All these registry keys are related to prevalent desktop security solutions.

Upon receiving a reply to its PING packet from google.com, the Trojan has the confirmation it needs to say that it has access to the Internet, it then proceeds to try to download more malware from 59.106.145.58, a server located in Japan. In fact, an HTTP GET request is sent to 59.106.145.58 with the following request URI:

test2.php?abc=value1?def=value2

with value1 being information on the antivirus software installed on the host and value2 being operating system information.
The Trojan also sends a cookie named ac to the server along with the GET request. The cookie is contains AES encrypted data about the user. Here is an example of the type of data it attempts to capture:

Outlook Express credentials
Protected Storage credentials
MSN Passport.Net credentials

As a result of a successful GET request, %SystemDir%\inetproc02x.cab is downloaded to the infected machine. This .cab file contains the following files:

winbase.dll
install.batwinbaseInst.exe
syicon.dll

After extraction from the .cab file, the batch file install.bat, copies all the files that were contained in the .cab to the folder %SystemDir%\wbem.
WinbaseInst.exe is then run which creates another service called "Windows NT Baseline" that points to basesvc.dll. The following registry keys are created in conjunction with the service:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BaseSvc\ParametersServicedll = %SystemDir%\wbem\ basesvc.dllServicemain = servicemainfunc

WinbaseInst.exe is thereafter deleted by install.bat.

We took a look at basesvc.dll in a disassembler and recognized in the .text section of this PE file, the following strings:

l 4b324fc8-1670-01d3-1278-5a47bf6ee188 is the Universally Unique Identifier, or UUID, that the vulnerable server service registers

l 199.166.133.90 is the IP address for a computer belong to the company TransCanada Pipeline. It's on the transcanada.com domain

l 139 is the TCP port for Netbios Session Service. This is the port that is used to connect file shares

What we have is an attempt by this piece of malware to exploit the computer at IP address 199.166.133.90 by sending it malformed DCE-RPC requests and relying on the vulnerable server service that is registered with UUID 4b324fc8-1670-01d3-1278-5a47bf6ee188. However, we were not seeing on the network traffic that showed that the routine above was actually called.
The .dll file exports the following 3 functions:

DllStartFunc
ServiceMainFunc
DllEntryPoint

Towards the end of the function ServiceMainFunc, a subroutine is invoked. This subroutine pauses the execution of the program for a long period of time. This is usually done to make reverse engineering difficult but also so that the Trojan will not attract attention immediately upon being executed.

Armed with these pieces of information, we edited this .dll file to change the sleep time to 1 ms and to change the target of this attack to an internal IP address. Finally, in order to call the desired function in basesvc.dll, we wrote a small loader. We edited ServiceMainFunc in our slightly modified .dll (we do not want to attack the computer system for TransCanada Pipeline) this function then seeks out potentially vulnerable Windows machines on our local network. Upon finding a vulnerable Windows machine, shellcode that is embedded in the Trojan is executed on the target machine. This shellcode instructs the newly compromised machine to contact IP address 59.106.145.58 in order to download a sample or variant of the Trojan.Gimmiv.

ClamAV detects these malcious files under the Trojan.Gimmiv (Trojan.Gimmiv-{1...7}) family.

It is worth nothing that none of the files associated with this Trojan are packed in any shape or form. Was this written by an inexperience coder or is this a deliberate taunt of the security community? The verdict is out on this one. Packing is a technique widely used by malware authors to prevent antimalware researchers from easily reversing malware binaries.

Friday, October 24, 2008

Why 114 rules for MS08-067?

With the release of Sourcefire's coverage for MS08-067, I've heard the same question repeatedly. "Why 114 rules? They were able to do it with just one." Since I wrote these rules, I'm the best to explain my solution.

I will not be going over the explicit nature of the vulnerability, but I will cover the protocol details that lead up to the vulnerability that make up my solution. The end goal of all of the rules is to detect attack traffic, while not alerting on benign traffic.

Detecting the underlying attack isn't that hard, in fact its pretty easy. While I could write one rule that looks for the basic information used in the attack, that basic information shows up all over the place. Printing to file transfers all include traffic that would set off the basic attack.

The hard part is making sure the detection only detects attacks, not benign traffic. My solution attempts to handle all of the potential methods for getting to the field that can be abused to exploit this vulnerability, and only do the detection of the attack on that field. The rules must handle all of the differences and neuances of the underlying protocols to limit detection to just the field in question. To that end, here are the primary neuancies that show up in nearly every DCERPC vulnerability.

First, the vulnerability is in a DCERPC service. DCERPC is accessable by a number of different methods:
  • netbios-ssn (139)
  • netbios-ds (445)
  • netbios-dgm (138)
  • NCACN-IP-TCP, direct DCERPC via TCP. (135, 593, or 1024 and above)
DCERPC over netbios has a number of protocol variations that need to be accounted for in the rules. Netbios has multiple common ways to get to DCERPC:
  • WriteAndX
  • Trans
Multiple SMB commands allow additional commands to be done after the original command in a single request. These commands have the nomeclaiture of "AndX". Examples of this would be:
  • WriteAndX with DCERPC
  • Trans with DCERPC
  • OpenAndX followed by Trans with DCERPC
  • OpenAndX followed by WriteAndX with DCERPC
  • OpenAndX followed by ReadAndX followed by WriteAndX with DCERPC
  • etc
SMB allows for normal and unicode string types, both of which are different at the packet level.

At the DCERPC layer, there even more differences. There are versions that differ greatly on the packet level:
  • v4 (request based)
  • v5 (session based)
Integers can be represented on the wire as big endian or as little endian. In addition, there is a 16 byte object identifier that may or may not be set in a given request.

Handling all of these permutations combines to a set of 114 rules. If you think I wrote all of these permutations by hand, you are nuts. I am firmly in the code-generation camp. Some time ago, I wrote a code generator that handles all of the permutations for me, allowing me to focus on the specifics of the attack, not the specifics of the protocol.

Thursday, October 23, 2008

Out of Band Microsoft Security Advisory MS08-067

Today, Microsoft released an out of band patch for a vulnerability concerning DCE/RPC that is being actively exploited by a Trojan.

We were busy today :D

Details on what we were busy with are available here: http://www.snort.org/vrt/advisories/vrt-rules-2008-10-23.html

More details on the Trojan are available here: http://www.microsoft.com/security/portal/Entry.aspx?Name=TrojanSpy:Win32/Gimmiv.A

Here's a link to the Microsoft bulletin: http://www.microsoft.com/technet/security/bulletin/ms08-067.mspx

Monday, October 20, 2008

Introduction to Network Penetration Testing

Overview

In an effort to broaden the audience and topic base for the VRT blog, this week we are going to take a very high level view of what a network penetration test looks like from the tester's perspective. Some of the techniques and ideas behind a high-level network penetration test will be described. This entry is not intended to be create a world of savvy pentesters out there, as nothing can replace knowledge and experience gained from previous tests, but it should at least get people started down the road toward successful penetration testing. Also, knowing what a network pentester does during their assessment will also help the pentester's customers have a better understanding of the process.

This overview is written with an interest in ease of use with no regard for stealth.

Process

A network penetration test, in its most simple form, can be described as multiple iterations of three steps -- reconnaissance, exploitation, and penetration. Each step leads to the next as well as back to the previous, providing more data for subsequent tests and attacks. Penetration adds new targets as more and more resources become available from new attack positions.

Reconnaissance

The first step of any penetration test is to become familiar with your target. For this discussion, we will assume the IP addresses for the target are known. The two most obvious steps for getting a high level view of your target are to find what ports are listening by using nmap and to get a basic understanding of your target's security posture by using a vulnerability scanner such as Nessus. Nmap will provide a list of all ports that are open (and are therefore potential attack vectors) and Nessus will attempt to provide a list of vulnerabilities found on the target hosts. Nessus's results cannot be taken at face value due to the nature of its testing, but it does provide a fairly broad view of what services are available, what service banners were provided, and guesses as to what vulnerabilities are present.

Using the reports from nmap and Nessus, we can begin to focus our attacks on hosts and services that further our goals of getting into the network. Most tests from Nessus do not actually perform an exploit. To attempt to exploit a vulnerability, an exploitation framework such as Metasploit, sample exploits from securityfocus.com or elsewhere on the 'Net, or a custom exploit needs to be used.

Exploitation

There are many types of exploits in the wild - denial of service, information leakage, arbitrary code execution, and escalation of privilege are but a few. Denial of service attacks are generally not very useful in penetration tests. If you DoS a machine, you cannot use that device to further your own attacks. This is, of course, unless that machine is preventing you from gaining deeper penetration into the network or provides logging functionality and stealth is desired. This is an advanced topic that won't be covered by this post. For now, we'll shuffle DoS attacks to the "store for the report" file and concentrate on vulnerabilities for which a working exploit that provides machine access is available.

Information leakage, which often does not get the credit its due when compared to the sexy arbitrary code execution, is an integral part of any pentest. Gaining additional information from a service, then feeding that new data through the complete penetration test cycle, is probably the single largest contributor to a successful pentest unless the network is widely vulnerable to a single code execution. For example, imagine a Web exploit that required knowledge of the valid Web root to work. Suddenly, a 404 Not Found that leaked the system path to the page is extremely useful.

Finally, the ultimate class of exploit, arbitrary code execution. With the ability to execute arbitrary code, anything is possible. This ability leads us to the next section, Penetration.

Penetration

The goal of a network penetration test is to gain deep access into the network. This is different than a network vulnerability assessment, where the breadth of vulnerabilities is sought. By exploiting vulnerabilites in a penetration test, we attempt to access more and more systems as we get behind obstacles. The most obvious way to achieve this goal is to install our tools and agents on devices as we compromise them and then use those new hosts as launch points for further attacks. Once we have system level access on a device, we can connect to any other device available to that machine. Another means of achieving deeper access is by abusing a trust relationship where a deeper machine can be made to act inappropriately due to data put on a device we can reach directly. The cycle then repeats with reconnaissance, exploitation, and penetration using this new host as our starting point.

Summary

This discussion was of a high-level view of network penetration testing. Several components of a more advanced test were not covered, such as identifying target hosts, the large amount of research required for a successful penetration test, or how to actually do the exploitation. The key takeaway from this post should be that penetration tests are a very iterative process -- gather information, act upon that information, feed new information into the cycle, and repeat until the goal has been achieved.

Saturday, October 11, 2008

Mac Transitions - Fixing Files

In the transition from Linux to Mac, I also ran across a small problem with Mac formatted text files on remote Linux machines. Line endings. I had assumed (and we all know what that means) that the Mac running OS X, being as it's userland roots lie firmly in the BSD camp, would be nice with it's text files and I wouldn't see any nonsense like I do with text files from Windows machines. It's not that they don't work, it's just that they do not look good in my text editor, Vim my favored pager, less and a few other cli programs I use.

Fortunately it is easy to fix the files, either in Vim itself, or with a little script I cooked up to do the job on a bunch of files all at once, here it is...


#!/bin/sh
#
# File name: mac2unix.sh
# Date: 2008/10/11 08:57
# Author: Nigel Houghton
# $Id: $
# Copyright: (c) Sourcefire Inc. 2008
#

if [ "$1" = "" ]
then
echo "Usage: $0 filename1 filename2...."
exit
fi

FILES="[email protected]"

changeit () {
OLDNAME="$file"
NEWNAME="$file.tmp_$$"
tr \\r \\n < $OLDNAME > $NEWNAME
mv $NEWNAME $OLDNAME
}

for file in $FILES
do
changeit
done


Of course, this could be done in several different ways and it could be extended for other systems (Windows for example) that use other line ending schemes. I put this script in my $HOME/bin/ so I can use it from wherever I happen to be in the filesystem.

Thursday, October 2, 2008

Perl Snippet

Recently, I have been moving Perl scripts from BSD and Linux machines onto OS X. Mostly, things are pretty smooth but today I had to change a script slightly so that I could read data from /private/var/tmp/ on OS X. The scripts I had on the other systems would read from /var/tmp/, on OS X there is a symlink to /private/var in the root partition, but it seemed to me that relying on the existence of symlinks is not a particularly good idea. Especially if I would need to move the scripts onto another system in the future.

I searched around my trusty Perl documentation and of course, online at http://perldoc.perl.org/ and I found I could use a special variable that contains the operating system name. Here's what I came up with:


my $infile = $ARGV[0];
my $os = $^O; # woohoo there's a special variable I can use for this

get_xmlpath();

sub get_xmlpath
{
if ( $os eq "darwin" )
{
$xmlpath = '/private/var/tmp/xml-data/';
}
else
{
$xmlpath = '/var/tmp/xml-data/';
}
$infile = "$xmlpath$infile.xml";
print "Using XML file: " . $infile . "\n";
return ($infile);
}

Could it be done using less lines? Of course, but then I think Perl Golf is just plain dumb. Disclaimer: this will not work on Win32, fortunately I never have to use Perl on Win32.