WIN 7可以使用RAW_SOCKET做TCP半连接扫描吗?
我在WIN 7环境下使用RAW_SOCKET做TCP半连接扫描,使用sendto函数发送TCP的syn请求,sendto函数返回值表明已经发送成功,但是wireshark并没有抓到相应的数据包,不知道为什么。麻烦大家帮帮忙!代码是我从网上找的:
[code=c#include <stdio.h>
#include <string.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#include "mstcpip.h"
#pragma comment(lib,"WS2_32.lib")
//定义目标主机的ip地址
char *DestIpAddr="10.8.180.125";
char *SourceIpAddr = "10.8.184.157";
//定义ip首部
typedef struct IpHeader
{
unsigned char Version_HLen; //首部长度ip版本号
unsigned char TOS; //服务类型TOS
unsigned short Length; //总长度
unsigned short Ident; //标识
unsigned short Flags_Offset;//标志位
unsigned char TTL; //生存时间TTL
unsigned char Protocol; //协议
unsigned short Checksum; //ip首部校验和
unsigned int SourceAddr; //源ip地址
unsigned int DestinationAddr;//目的ip地址
}Ip_Header;
//tcp 标志位
#define URG 0x20
#define ACK 0x10
#define PSH 0x08
#define RST 0x04
#define SYN 0x02
#define FIN 0x01
//定义tcp首部
typedef struct TcpHeader
{
USHORT SrcPort; //16位源端口
USHORT DstPort; //16位目的端口
unsigned int SequenceNum; //32位序号
unsigned int Acknowledgment;//32位确认序号
unsigned char Hdrlen; //首部长度
unsigned char Flags; //6位标志位
USHORT AdvertisedWindow; //16位窗口大小
USHORT Checksum; //16位校验和
USHORT UrgPtr; //16位紧急指针
}Tcp_Header;
//函数引用
//分析数据包
int PacketAnalyzer(char*);
//发送数据吧
int SendTCPSYNPacket(int);
//主函数
int main(int argc,char **argv)
{
//开始端口
int PortStart=80;
//结束端口
int PortEnd=90;
//套接字
SOCKET RecSocket;
int Result;
char RecvBuf[65535]={0};
//定时器的频率
LARGE_INTEGER nFreq;
char Name[255];
//起始获得定时器的值
LARGE_INTEGER StartTime;
//终止定时器的值
LARGE_INTEGER EndTime;
HANDLE hCon;
WSADATA wsaData;
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD dwBytesReturned=0;
struct hostent *pHostent;
//初始化SOCKET
Result=WSAStartup(MAKEWORD(2,1),&wsaData);
if(Result==SOCKET_ERROR)
{
printf("WSAStartup failed with error %d\n",Result);
return 0;
}
//创建接收数据的套接字
RecSocket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(Result==SOCKET_ERROR)
{
printf("socket failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//获得本机ip地址
Result=gethostname(Name,255);
if(Result==SOCKET_ERROR)
{
printf("gethostname1 failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
pHostent=(struct hostent*)malloc(sizeof(struct hostent));
pHostent=gethostbyname(Name);
SOCKADDR_IN sock;
sock.sin_family=AF_INET;
sock.sin_port=htons(5555);
memcpy(&sock.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
//绑定套接字
Result=bind(RecSocket,(PSOCKADDR)&sock,sizeof(sock));
if(Result==SOCKET_ERROR)
{
printf("bind failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//设置SOCK_RAW为SIO_RCVALL
Result=WSAIoctl(
RecSocket,
SIO_RCVALL,//表示接收所有ip数据包
&dwBufferInLen,
sizeof(dwBufferInLen),
&dwBufferLen,
sizeof(dwBufferLen),
&dwBytesReturned,NULL,NULL);
if(Result==SOCKET_ERROR)
{
printf("WSAIoctl failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
hCon=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hCon,&bInfo);
if(QueryPerformanceFrequency(&nFreq))
{
//获取定时器的值
QueryPerformanceCounter(&StartTime);
//循环扫描每个端口
for(int p=PortStart;p<=PortEnd;p++)
{
//发送构造的tcpsyn数据包
SendTCPSYNPacket(p);
//循环监听是否有数据包到达
while(true)
{
memset(RecvBuf,0,sizeof(RecvBuf));
Result=recv(RecSocket,RecvBuf,sizeof(RecvBuf),0);
if(Result==SOCKET_ERROR)
{
printf("recv failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//分析数据包
Result=PacketAnalyzer(RecvBuf);
if(Result==0)
{
continue;
}
else
{
break;
}
}
SetConsoleTextAttribute(hCon,14);
QueryPerformanceCounter(&EndTime);
}//end for
}
//技术时间
double fInterval=EndTime.QuadPart-StartTime.QuadPart;
printf("Total Time:%ffms\n",fInterval*1000/(double)nFreq.QuadPart);
SetConsoleTextAttribute(hCon,bInfo.wAttributes);
//关闭套接字
if(closesocket(RecSocket)==SOCKET_ERROR)
{
printf("closesocket failed with error %d\n",WSAGetLastError());
return 0;
}
if(WSACleanup()==SOCKET_ERROR)
{
printf("WSACleanup failed with error %d\n",WSAGetLastError());
return 0;
}
return 1;
}
//计算校验和
USHORT checksum(USHORT *buffer,int size)
{
unsigned long cksum=0;
while (size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR*)buffer;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
//发送tcp协议数据
//为了独立性,协议的数据结构全部定义在内部
int SendTCPSYNPacket(int Port)
{
//定义ip首部
typedef struct ipHeader
{
u_char Version_HLen;
u_char TOS;
short Length;
short Ident;
short Flags_Offset;
u_char TTL;
u_char Protocol;
short Checksum;
unsigned int SourceAddr;
unsigned int DestinationAddr;
}Ip_Header;
//定义tcp伪首部
typedef struct PsdTcpHeader
{
unsigned long SourceAddr;
unsigned long DestinationAddr;
char Zero;
char Protcol;
unsigned short TcpLen;
}PSD_Tcp_Header;
//定义tcp首部
typedef struct tcp_hdr
{
USHORT SrcPort;
USHORT DstPort;
unsigned int SequenceNum;
unsigned int Acknowledgement;
unsigned char HdrLen;
unsigned char Flags;
USHORT AdvertisedWindow;
USHORT Checksum;
USHORT UrgPtr;
}Tcp_Header;
//本级ip地址
struct in_addr localaddr;
//本地主机名
char HostName[255];
struct hostent *Hostent;
WSADATA wsaData;
//发送用套接字
SOCKET SendSocket;
SOCKADDR_IN addr_in;
//表示ip首部
Ip_Header ipHeader;
//表示tcp首部
Tcp_Header tcpHeader;
//表示tcp伪首部
PSD_Tcp_Header psdHeader;
//发送缓冲区
char szSendBuf[100]={0};
BOOL flag;
int nTimeOver;
int Result;
Result=WSAStartup(MAKEWORD(2,1),&wsaData);
if(Result==SOCKET_ERROR)
{
printf("WSAStartup failed with error%d\n",Result);
return 0;
}
if((SendSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("WSASocket failed with error %d\n",WSAGetLastError());
return false;
}
flag=true;
if(setsockopt(SendSocket,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt failed with error %d\n",WSAGetLastError());
return false;
}
nTimeOver=1000;
if(setsockopt(SendSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&nTimeOver,sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt failed with error %d\n\n",WSAGetLastError());
return false;
}
addr_in.sin_family =AF_INET;
addr_in.sin_port =htons(1000);
addr_in.sin_addr .S_un.S_addr =inet_addr(DestIpAddr);
//获取本地主机
Result=gethostname(HostName,255);
if(Result==SOCKET_ERROR)
{
printf("gethostname12 failed with error %d\n",WSAGetLastError());
return 0;
}
Hostent=(struct hostent*)malloc(sizeof(struct hostent));
Hostent=gethostbyname(HostName);
//填充ip首部
//版本和长度
ipHeader.Version_HLen=(4<<4|sizeof(ipHeader)/sizeof(unsigned long));
//服务类型
ipHeader.TOS=0;
ipHeader.Length=htons(sizeof(ipHeader)+sizeof(tcpHeader));
//16为标识
ipHeader.Ident=1;
ipHeader.Flags_Offset=0;
ipHeader.TTL=128;
ipHeader.Protocol=IPPROTO_TCP;
ipHeader.Checksum=0;
ipHeader.SourceAddr=inet_addr(SourceIpAddr) ;
ipHeader.DestinationAddr=inet_addr(DestIpAddr);
//填充tcp首部
tcpHeader.DstPort=htons(Port);
tcpHeader.SrcPort=htons(6666);
tcpHeader.Acknowledgement=0;
tcpHeader.HdrLen=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.Flags=2;
tcpHeader.AdvertisedWindow=htons(512);
tcpHeader.UrgPtr=0;
tcpHeader.Checksum=0;
//填写tcp伪首部
psdHeader.SourceAddr=ipHeader.SourceAddr;
psdHeader.DestinationAddr=ipHeader.DestinationAddr;
psdHeader.Zero=0;
psdHeader.Protcol=IPPROTO_TCP;
psdHeader.TcpLen=htons(sizeof(tcpHeader));
//计算tcp校验和
memcpy(szSendBuf,&psdHeader,sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader));
tcpHeader.Checksum=checksum((USHORT*)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
//计算ip校验和
memcpy(szSendBuf,&ipHeader,sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader),&tcpHeader,sizeof(tcpHeader));
tcpHeader.Checksum=checksum((USHORT*)szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader));
//更新内容
memcpy(szSendBuf,&ipHeader,sizeof(ipHeader));
Result=sendto(SendSocket,szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader),0,(struct sockaddr*)&addr_in,sizeof(addr_in));
if(Result==SOCKET_ERROR)
{
printf("sendto failed with error%d\n",WSAGetLastError());
return 0;
}
if(closesocket(SendSocket)==SOCKET_ERROR)
{
printf("closesocket failed with error%d\n",WSAGetLastError());
return 0;
}
if(WSACleanup()==SOCKET_ERROR)
{
printf("WSACleanup failed with error%d\n",WSAGetLastError());
return 0;
}
return 1;
}
//数据包分析
int PacketAnalyzer(char*PacketBuffer)
{
Ip_Header *pIpheader;
int iProtocol,iTTL;
char szSourceIP[16],szDestIP[16];
SOCKADDR_IN saSource,saDest;
pIpheader=(Ip_Header*)PacketBuffer;
iProtocol=pIpheader->Protocol;
saSource.sin_addr.S_un.S_addr=pIpheader->SourceAddr;
::strcpy (szSourceIP,inet_ntoa(saSource.sin_addr ));
saDest.sin_addr .S_un .S_addr=pIpheader->SourceAddr;
::strcpy(szDestIP,inet_ntoa(saDest.sin_addr ));
iTTL=pIpheader->TTL;
int iIphLen=sizeof(unsigned long)*pIpheader->Version_HLen&0x0f;
if(iProtocol==IPPROTO_TCP)
{
Tcp_Header*pTcpHeader;
pTcpHeader=(Tcp_Header*)(PacketBuffer+iIphLen);
if(pIpheader->SourceAddr==inet_addr(DestIpAddr))
{
//如果返回rst
if(pTcpHeader->Flags &RST)
{
printf("Port %d Close\n",ntohs(pTcpHeader->SrcPort));
return 1;
}
else if((pTcpHeader->Flags &SYN)&&(pTcpHeader->Flags &ACK))
{
//表示端口开放
printf("Port %d Open\n",ntohs(pTcpHeader->SrcPort ));
return 1;
}
}
}
return 0;
}][/code]