使用SMB协议实现Windows操作系统的检测
来源:互联网 发布:特锐地产数据 编辑:程序博客网 时间:2024/06/16 04:48
SMB协议中,在他们的会话的时候,微软在一些特别的域中给出了操作系统的具体的版本,这些信息我们可以用来监测Windows操作系统。
具体看下面的代码,定义了SMB一些协议的结构
// SMB.h: interface for the CSMB class.
//
//////////////////////////////////////////////////////////////////////
#include <winsock2.h>
typedef unsigned char UCHAR; // 8 unsigned bits
typedef unsigned short USHORT; // 16 unsigned bits
typedef unsigned long ULONG; // 32 unsigned bits
#pragma pack(1)
typedef struct netbiosHeader
{
UCHAR Type; // Type of the packet
UCHAR Flags; // Flags
USHORT Length; // Count of data bytes (netbios header not included)
} NETBIOSHEADER,*PNETBIOSHEADER;
//4
//////////////////////////////////////////////////////////////////////////
///////////////
/////////////// SMB HEADER
///////////////
//////////////////////////////////////////////////////////////////////////
typedef struct NegoRequestHead
{
UCHAR Protocol[4]; // Contains 0xFF,'SMB'
UCHAR Command; // Command code
union
{
struct
{
UCHAR ErrorClass; // Error class
UCHAR Reserved; // Reserved for future use
USHORT Error; // Error code
} DosError;
ULONG Status; // 32-bit error code
} Status;
UCHAR Flags; // Flags
USHORT Flags2; // More flags
union
{
USHORT Pad[6]; // Ensure section is 12 bytes long
struct
{
USHORT PidHigh; // High part of PID
ULONG Unused; // Not used
ULONG Unused2;
} Extra;
}pad;
USHORT Tid; // Tree identifier
USHORT Pid; // Caller's process id
USHORT Uid; // Unauthenticated user id
USHORT Mid; // multiplex id
// UCHAR WordCount; // Count of parameter words
// USHORT* ParameterWords; // The parameter words
// USHORT ByteCount; // Count of bytes
// UCHAR* Buffer; // The bytes
}NEGOREQUESTHEAD,*PNEGOREQUESTHEAD;
//32
//**************************************************************
//**********************END*************************************
//////////////////////////////////////////////////////////////////////////
///////////////
/////////////// SMB REQUEST HEADER
///////////////
//////////////////////////////////////////////////////////////////////////
/*
struct RequestHead
{
UCHAR WordCount; //Count of parameter words = 0
USHORT ByteCount; //Count of data bytes
struct {
UCHAR BufferFormat; //0x02 -- Dialect
UCHAR DialectName[]; //ASCII null-terminated string
} Dialects[];
};
*/
//**************************************************************
//**********************END*************************************
// Echo SMB HEADER
struct EchoSMBHeader
{
UCHAR WordCount; //Count of parameter words = 17
USHORT DialectIndex; //Index of selected dialect
UCHAR SecurityMode; //Security mode:
// bit 0: 0 = share, 1 = user
// bit 1: 1 = encrypt passwords
USHORT MaxMpxCount; //Max pending multiplexed requests
USHORT MaxNumberVcs; //Max VCs between client and server
ULONG MaxBufferSize; //Max transmit buffer size
ULONG MaxRawSize; //Maximum raw buffer size
ULONG SessionKey; //Unique token identifying this session
ULONG Capabilities; //Server capabilities
ULONG SystemTimeLow; //System (UTC) time of the server (low).
ULONG SystemTimeHigh; //System (UTC) time of the server (high).
USHORT ServerTimeZone; //Time zone of server (min from UTC)
UCHAR EncryptionKeyLength;// Length of encryption key.
USHORT ByteCount; //Count of data bytes
//UCHAR EncryptionKey[]; The challenge encryption key
//UCHAR OemDomainName[]; The name of the domain (in OEM chars)
}; //37
//REQUEST DATA HEADER
struct RequestData
{
UCHAR WordCount; //Count of parameter words = 13
UCHAR AndXCommand; //Secondary (X) command; 0xFF = none
UCHAR AndXReserved;// Reserved (must be 0)
USHORT AndXOffset; //Offset to next command WordCount
USHORT MaxBufferSize; //Client's maximum buffer size
USHORT MaxMpxCount; //Actual maximum multiplexed pending requests
USHORT VcNumber; //0=first (only),nonzero=additional VC number
ULONG SessionKey; //Session key (valid iff VcNumber != 0)
USHORT CaseInsensitivePasswordLength; //Account password size, ANSI
USHORT CaseSensitivePasswordLength; //Account password size, Unicode
ULONG Reserved; //must be 0
ULONG Capabilities; //Client capabilities
USHORT ByteCount; //Count of data bytes; min = 0
// UCHAR CaseInsensitivePassword[]; Account Password, ANSI
// UCHAR CaseSensitivePassword[]; Account Password, Unicode
// STRING AccountName[]; Account Name, Unicode
// STRING PrimaryDomain[]; Client's primary domain, Unicode
// STRING NativeOS[]; Client's native operating system, Unicode
// STRING NativeLanMan[]; Client's native LAN Manager type, Unicode
};
//29
//DATA Each
struct EchoData
{
UCHAR WordCount; //Count of parameter words = 3
UCHAR AndXCommand; //Secondary (X) command; 0xFF = none
UCHAR AndXReserved; //Reserved (must be 0)
USHORT AndXOffset; //Offset to next command WordCount
USHORT Action; //Request mode: bit0 = logged in as GUEST
USHORT ByteCount; //Count of data bytes
// STRING NativeOS[]; //Server's native operating system
// STRING NativeLanMan[]; Server's native LAN Manager type
// STRING PrimaryDomain[]; Server's primary domain
}; //9
class CSMB
{
private:
CString szComputerName;
CString szIP;
WSADATA wsaData;
struct sockaddr_in name;
struct sockaddr_in local;
void Convert(char* buf);
ULONG sessionKey;
UCHAR securityMode;
int s;
public:
bool InitSocket();
int SendNBSS();
bool RecvNBSS();
int SendNegotiate();
bool RecvNegotiate();
int SendSesssetupX();
bool RecvSesssetupX();
HANDLE hEvent;
CSMB(CString strIP,CString szComuputerName);
virtual ~CSMB();
CString szNativeOS;
CString szNativeLM;
CString szDomain;
void DoSMBScan();
DWORD static BeginScan(LPVOID smb1);
};
#endif // !defined(AFX_SMB_H__29408F98_890D_4CE5_A284_55985EA816AF__INCLUDED_)
具体的SMB协议中我们需要下面的步骤:
1)初始化Socket
2)发送Netbios的信息
3)SMB的协商过程
4)发送建立握手的过程
// SMB.cpp: implementation of the CSMB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <windows.h>
#include "NetScan.h"
#include "SMB.h"
#define SMB_PORT 139
#include <winsock2.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define PC_NETWORK_PROGRAM_10 "/x02PC NETWORK PROGRAM 1.0/0"
#define MICROSOFT_NETWORKS_103 "/x02MICROSOFT NETWORKS 1.03/0"
#define MICROSOFT_NETWORKS_30 "/x02MICROSOFT NETWORKS 3.0/0"
#define LANMAN10 "/x02LANMAN1.0/0"
#define LM12 "/x02LM1.2X002/0"
#define SANBA "/x02SAMBA/0"
#define NTLM012 "/x02NT LM 0.12/0"
#define NTLANMAN10 "/x02NT LANMAN 1.0/0"
#define DOMAIN "WORKGROUP/0"
#define NATIVEOS "Unix/0"
#define NATIVELANMAN "Samba/0"
CSMB::CSMB(CString strIP,CString strComputerName)
{
this->szComputerName = strComputerName;
szIP = strIP;
szDomain = _T("");
szNativeOS = _T("");
szNativeLM = _T("");
hEvent = CreateEvent(NULL,true,false,NULL);
}
bool CSMB::InitSocket()
{
if(WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
return false;
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
DWORD nIP = inet_addr(szIP);
ZeroMemory((PVOID)&name,sizeof(name));
name.sin_family = AF_INET;
name.sin_port = htons(SMB_PORT);
name.sin_addr.S_un.S_addr = nIP;
// local.sin_family = AF_INET;
// local.sin_port = ANY;
// local.sin_addr.S_un = INADDR_ANY;
if(s == INVALID_SOCKET)
return false;
return true;
}
int CSMB::SendNBSS()
{
int iRet = connect(s,(struct sockaddr*)&name,sizeof(name));
if(iRet == -1)
return 0;
unsigned char buf[1024] = {0};
buf[0] = 0x81; //0x81 对应一个NETBIOS会话请求。这个代码在客户端发送它的NETBIOS名字到服务器是使用。
//0x82 对应一个NETBIOS会话应答。这个代码在服务器向客户端批准NETBIOS会话时使用
//0x00 对应一个会话消息。这个代码总是在SMB会话中被使用。
buf[1] = 0; // always 0
buf[2] = 0x00;
buf[3] = 0x48;
buf[4] = 0x20;
Convert((char*)&buf[5]);
iRet = send(s,(char*)buf,72,0);
return iRet;
}
bool CSMB::RecvNBSS()
{
unsigned char buf[1024] = {0};
int len = 1024;
fd_set fread;
fd_set ferror;
FD_ZERO(&fread);
FD_ZERO(&ferror);
FD_SET(s, &fread);
FD_SET(s, &ferror);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if(select(0,&fread,NULL, &ferror,&timeout) >0)
{
if(FD_ISSET(s,&fread))
{
int iRet = recv(s,(char*) buf , len,0);
}
if(buf[0] == 0x82)
{
return true;
}
else
return false;
}
return false;
}
int CSMB::SendNegotiate()
{
int iRet ;
int len = 0;
unsigned char buf[1024] = {0} ;
// Constructor Netbios Header
NETBIOSHEADER nHeader ;
nHeader.Flags = 0x00;
nHeader.Type = 0x00;
nHeader.Length = htons(0x00a4);
//constructor SMB Header
NEGOREQUESTHEAD negoRequestHead;
ZeroMemory((LPVOID)&negoRequestHead, 32);
strcpy((char*)&negoRequestHead.Protocol[1],(char*)"SMB");
negoRequestHead.Protocol[0] = 0xFF;
negoRequestHead.Command = 0x72;
// ZeroMemory((LPVOID)negoRequestHead.Status.Status, sizeof(negoRequestHead.Status));
negoRequestHead.Flags = 0x00;
negoRequestHead.Flags2 = 0x00;
// ZeroMemory((LPVOID)negoRequestHead.pad.Pad,sizeof(negoRequestHead.pad));
negoRequestHead.Tid = 0x0000;
negoRequestHead.Pid = htons(GetCurrentProcessId());
negoRequestHead.Uid = 0x0000;
negoRequestHead.Mid = negoRequestHead.Pid + 100;
//Constructor Request Header
//negoRequestHead.WordCount = 0x00;
//negoRequestHead.ByteCount = htons(0x81);
int i =0;
memcpy((void*)&buf[i],(void*)&nHeader,sizeof(nHeader));
i = i + sizeof(nHeader);
memcpy((void*) &buf[i], (void*) &negoRequestHead,32);
i = i + 32;
buf[i++] = 0x00;
buf[i++] = 0x81;
buf[i++] = 0x00;
memcpy((void*) &buf[i],(void*)PC_NETWORK_PROGRAM_10, 24);
i = i + 24;
memcpy((void*) &buf[i],(void*)MICROSOFT_NETWORKS_103, 25);
i= i+ 25;
memcpy((void*) &buf[i],(void*)MICROSOFT_NETWORKS_30, 24);
i = i+ 24;
memcpy((void*) &buf[i],(void*)LANMAN10, 11);
i = i + 11;
memcpy((void*) &buf[i],(void*)LM12, 11);
i = i + 11;
memcpy((void*) &buf[i],(void*)SANBA, 7);
i = i + 7;
memcpy((void*) &buf[i],(void*)NTLM012, 12);
i = i + 12;
memcpy((void*) &buf[i],(void*)NTLANMAN10, 15);
i = i + 15;
iRet = send(s,(char*)buf,i,0);
return iRet;
}
bool CSMB::RecvNegotiate()
{
unsigned char buf[1024] = {0};
int len = 1024;
fd_set fread;
fd_set ferror;
FD_ZERO(&fread);
FD_ZERO(&ferror);
FD_SET(s, &fread);
FD_SET(s, &ferror);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int iRet =0;
if(select(0,&fread,NULL, &ferror,&timeout) >0)
{
if(FD_ISSET(s,&fread))
{
iRet= recv(s,(char*) buf , len,0);
}
else
return false;
}
else
return false;
NETBIOSHEADER nHeader ;
NEGOREQUESTHEAD negoRequestHead;
struct EchoSMBHeader data;
if(iRet < sizeof(nHeader) + 32 + 37)
{
return false;
}
memcpy((void*)&nHeader,buf,sizeof(nHeader));
int i = sizeof(nHeader);
memcpy((void*)&negoRequestHead,(void*)&buf[i],32);
i = i + 32;
memcpy((void*)&data, (void*)&buf[i],37);
i = i + 37;
char EncryptionKey[17] = {0};
memcpy((void*)&EncryptionKey,&buf[i], 16);
i = i+ 16;
securityMode = data.SecurityMode;
sessionKey = data.SessionKey;
return true;
}
int CSMB::SendSesssetupX()
{
int iRet ;
int len = 0;
unsigned char buf[1024] = {0} ;
// Constructor Netbios Header
NETBIOSHEADER nHeader ;
nHeader.Flags = 0x00;
nHeader.Type = 0x00;
nHeader.Length = htons(0x54);
//constructor SMB Header
NEGOREQUESTHEAD negoRequestHead;
ZeroMemory((LPVOID)&negoRequestHead, 32);
strcpy((char*)&negoRequestHead.Protocol[1],(char*)"SMB");
negoRequestHead.Protocol[0] = 0xFF;
negoRequestHead.Command = 0x73;
// ZeroMemory((LPVOID)&negoRequestHead.Status.Status, sizeof(negoRequestHead.Status));
negoRequestHead.Flags = 0x08;
negoRequestHead.Flags2 = htons(0x0001);
// ZeroMemory((LPVOID)negoRequestHead.pad.Pad,sizeof(negoRequestHead.pad));
negoRequestHead.Tid = 0x0000;
negoRequestHead.Pid = htons(GetCurrentProcessId());
negoRequestHead.Uid = 0x0000;
negoRequestHead.Mid = negoRequestHead.Pid + 100;
// negoRequestHead.WordCount = 0x00;
// negoRequestHead.ByteCount =
//Constructor Request Header
struct RequestData data;
ZeroMemory((void*)&data,29);
data.WordCount = 0x0d;
data.AndXCommand = 0xFF;
data.AndXReserved = 0x00;
data.AndXOffset = 0x00;
data.MaxBufferSize = 0xffff;
data.MaxMpxCount = 0x0002;
data.VcNumber = negoRequestHead.Pid;
data.SessionKey = sessionKey;
data.CaseInsensitivePasswordLength =0x0001;
data.CaseSensitivePasswordLength = 0x0000;
data.Reserved = 0x00;
data.Capabilities = 0x00;
data.ByteCount = htons(0x1700);
int i =0;
memcpy((void*)&buf[i],(void*)&nHeader,sizeof(nHeader));
i = i + sizeof(nHeader);
memcpy((void*) &buf[i], (void*) &negoRequestHead, 32);
i = i + 32;
memcpy((void*) &buf[i],(void*) &data, 29);
i = i + 29;
buf[i++] = 0x00;
buf[i++] = 0x00;
memcpy((void*) &buf[i],(void*)DOMAIN, 10);
i = i + 10;
memcpy((void*) &buf[i],(void*)NATIVEOS, 5);
i= i+ 5;
memcpy((void*) &buf[i],(void*)NATIVELANMAN, 6);
i = i+ 6;
iRet = send(s,(char*)buf,i,0);
return iRet;
}
void CSMB::Convert(char* buf)
{
char temp[16] = {0x20};
strcpy(temp, szComputerName);
//temp[szComputerName.GetLength()] = 0x20;
FillMemory((LPVOID)&temp[szComputerName.GetLength()], 16-szComputerName.GetLength(), 0x20);
int i=0;
for(i=0; i< 16; i++)
{
char c = temp[i];
int j = c/16;
int k = c%16;
buf[2*i] = j + 'A';
buf[2*i+1] = k + 'A';
}
buf[32] = 0x00;
buf[33] = 0x20;
for(i=17; i<33;i++)
{
buf[i*2] = 'C';
buf[i*2 + 1] = 'A';
}
buf[66] = 0;
}
bool CSMB::RecvSesssetupX()
{
unsigned char buf[1024] = {0};
int len = 1024;
fd_set fread;
fd_set ferror;
FD_ZERO(&fread);
FD_ZERO(&ferror);
FD_SET(s, &fread);
FD_SET(s, &ferror);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int iRet =0;
if(select(0,&fread,NULL, &ferror,&timeout) >0)
{
if(FD_ISSET(s,&fread))
{
iRet= recv(s,(char*) buf , len,0);
}
else
return false;
}
else
return false;
NETBIOSHEADER nHeader ;
NEGOREQUESTHEAD negoRequestHead;
struct EchoData data;
if(iRet < sizeof(nHeader) + 32 + 9)
{
return false;
}
closesocket(s);
memcpy((void*)&nHeader,buf,sizeof(nHeader));
int i = sizeof(nHeader);
memcpy((void*)&negoRequestHead, &buf[i],32);
i = i + 32;
memcpy((void*)&data, &buf[i],9);
i = i + 9;
char NativeOs[256] = {0};
strcpy(NativeOs,(char*)&buf[i]);
i = i + strlen(NativeOs) + 1;
char NativeLanMan[256] = {0};
strcpy(NativeLanMan,(char*)&buf[i]);
i = i + strlen(NativeLanMan) + 1;
char Domain[256] = {0};
strcpy(Domain,(char*)&buf[i]);
this->szNativeLM = NativeLanMan;
this->szNativeOS = NativeOs;
this->szDomain = Domain;
return true;
}
void CSMB::DoSMBScan()
{
if(!InitSocket())
return ;
int iRet = SendNBSS();
if(iRet <= 0)
return ;
if(!RecvNBSS())
return ;
iRet = SendNegotiate();
if(iRet <=0)
return ;
if(!RecvNegotiate())
return ;
iRet = SendSesssetupX();
if(iRet <=0)
return ;
RecvSesssetupX();
// ResetEvent(hEvent);
return ;
}
/*
void CSMB::DoSMBScan()
{
DWORD IDThread;
// CWinThread temp ;
// temp.CreateThread(0,0);
HANDLE hThread = ::CreateThread(NULL, // no security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)BeginScan, // thread function
this, // no thread function argument
0, // use default creation flags
&IDThread); // returns thread identifier
::ResumeThread(hThread);
DWORD dwMilliseconds = 15000;
// SetEvent(hEvent);
DWORD dRet = WaitForSingleObject(hEvent, dwMilliseconds);
if(dRet == WAIT_TIMEOUT)
{
::ExitThread(1);
Sleep(2000);
}
}
*/
DWORD CSMB::BeginScan(LPVOID smb1)
{
// SetEvent(smb->hEvent);
CSMB *smb = (CSMB*) smb1;
if(!smb->InitSocket())
return 1;
int iRet = smb->SendNBSS();
if(iRet <= 0)
return 1;
if(!smb->RecvNBSS())
return 1;
iRet = smb->SendNegotiate();
if(iRet <=0)
return 1;
if(!smb->RecvNegotiate())
return 1;
iRet = smb->SendSesssetupX();
if(iRet <=0)
return 1;
smb->RecvSesssetupX();
SetEvent(smb->hEvent);
return 1;
}
CSMB::~CSMB()
{
// shutdown(this->s, 1);
WSACleanup();
}
基于篇幅的问题,这里没有办法把整个工程放进去,只好把头文件和CPP文件粘贴在这里。希望对大家有所帮助!!!
- 使用SMB协议实现Windows操作系统的检测
- 使用SMB协议实现Windows操作系统的检测
- acccheck ----- 破解使用SMB协议的Windows用户密码
- 传说中的利用SMB协议检测操作系统类型CODE
- 传说中的利用SMB协议检测操作系统类型CODE
- smb windows中使用的文件共享协议(主要用于与windows互通)
- SMB协议实现 Samba 3.5.12 发布
- SMB协议
- SMB协议
- SMB协议
- smb协议
- SMB协议
- 使用SMB协议远程读写文件
- Mac 使用smb协议连接FTP服务器
- 基于SMB协议的共享文件读写
- SMB协议的共享文件读写
- 基于SMB协议的共享文件读写
- 基于SMB协议的共享文件读写
- GCC-3.4.6源代码学习笔记(73)
- QT for linux 的错误 undefined reference to 'FcFreeTypeQueryFace' 的解决方法
- 3083 Children of the Candy Corn
- [嵌入式]抱怨一下RA8806控制器(带中文字库)
- 电容的作用
- 使用SMB协议实现Windows操作系统的检测
- js判断浏览器的类型
- myEclipse8.5 注册机
- 完整验证码
- 收藏两个位图切割实现动画效果的例子(一个是用位图切割的方式,另一个是用scrollRect)
- Sql 删除所有表
- static 在C/C++中的用法
- 八种方式启动JAVA程序
- ram size issue for building CE image