#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)//0x80000000|0x18000000|0x00000001
#define sourceport 8888
char srcIP[20] ="" ; //源ip
char tgtIP[20] ="" ; //目标ip
int portnow; //正在扫描的端口
int start,endscan;
typedef struct ip_hdr
{
unsigned char h_verlen; //4位首部长度,4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct tsd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSD_HEADER;
int send_packet(); //发送数据函数
int rec(); //监听数据函数
//解析函数
void check_port(char *buffer)
{
IP_HEADER *ipHeader;//IP_HEADER型指针
TCP_HEADER *tcpHeader;//TCP_HEADER型指针
ipHeader = (IP_HEADER *)buffer;
tcpHeader = (TCP_HEADER *) (buffer+sizeof(IP_HEADER));
if(ipHeader->sourceIP != inet_addr(tgtIP))
{
return;
}
for(int tmp=start;tmp<=endscan+1;tmp++)
{
//SYN+ACK -> 2+16=18
if(tcpHeader->th_flag == 18 && tcpHeader->th_sport == htons(tmp))
{
printf("[Found]\t%s\tport\t%d\tOpen\n",tgtIP,tmp);
}
}
}
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);
}
int main( int argc , char *argv[] )
{
WSADATA WSAData;
DWORD thread_ID = 1;
char hostname[128] ={0} ;
HANDLE ThreadHandle[1024];
struct hostent *host_entry;
printf("useage: scan 目标ip startport endport\n");
printf("most 60 ports scaned at one time\n");
if( argc != 4 )//检查命令行参数
{
exit( 0 );
}
if ( WSAStartup(MAKEWORD(2,0) , &WSAData) )
{
printf("WSAStartup Error...\n");
exit(0);
}
strcpy(tgtIP,argv[1]);//得到目标主机的ip地址
gethostname(hostname,128);//获取本机主机名
host_entry= gethostbyname(hostname);//获取本机ip地址结构
if(host_entry != NULL)
strcpy(srcIP, inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0])));//得到本机ip地址
start=atoi(argv[2]);
endscan=atoi(argv[3]);
if(((endscan-start)>=60)||((endscan-start)<0))
{printf("input error!\nplease check your input ports,60 ports can be scaned at one time!\n");
exit(0);
}
printf("\nsourceip\t%s\n",srcIP);
printf("destination\t%s\n",tgtIP);
printf("port range\t%d--%d\n",start,endscan);
//开启新线程,接受数据包,分析返回的信息
HANDLE RecvHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rec,NULL,0,(LPDWORD)&thread_ID);
printf("\n接受线程成功开启!\n\n");
Sleep(500);
portnow=start;
for(int temp = 0;temp<=(endscan-start); temp++)
{
++thread_ID;
//开启新线程,发送数据包
printf("开启发送线程%d\n",temp+1);
ThreadHandle[temp] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_packet,NULL,0,(LPDWORD)&thread_ID);
Sleep(100);
portnow++;
}
DWORD WaitThread1 = WaitForMultipleObjects((DWORD)(portnow-start), ThreadHandle , TRUE , INFINITE );
DWORD WaitThread2 = WaitForSingleObject(RecvHandle, INFINITE);
if( WaitThread1 != WAIT_FAILED)
{
for( int n = 0 ; n <=(endscan-start); n++ )
{
CloseHandle( ThreadHandle[n] );
printf("正在关闭发送线程%d\n",n+1);
}
}
if( WaitThread2 != WAIT_FAILED)
{CloseHandle( RecvHandle );
printf("\n正在关闭接受线程!\n");
}
WSACleanup();
return 0;
}
//发送数据包的函数
int send_packet()
{
SOCKET sendSocket;
BOOL flag;
int timeout;
SOCKADDR_IN sin;
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[60] = {0}; //发送包的缓冲区
int ret;
unsigned long source_ip;
unsigned long target_ip;
//初始化一个原始socket
if((sendSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Socket Setup Error...\n");
return 0;
}
//设置自己填充数据包
if(setsockopt(sendSocket, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)) == SOCKET_ERROR)
{
printf("Setsockopt IP_HDRINCL Error...\n");
return 0;
}
//设置超时时间
timeout = 1000;
if(setsockopt(sendSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
printf("Setsockopt SO_SNDTIMEO Error...\n");
return 0;
}
target_ip = inet_addr(tgtIP);
source_ip = inet_addr(srcIP);
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(portnow);
sin.sin_addr.s_addr = target_ip;
//填充IP首部
ipHeader.h_verlen = (4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
ipHeader.total_len = htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident = 1;
ipHeader.frag_and_flags = 0x40;
ipHeader.ttl = 128;
ipHeader.proto = IPPROTO_TCP;
ipHeader.checksum = 0;
ipHeader.sourceIP = source_ip;//源IP
ipHeader.destIP = target_ip;//目的IP
//填充TCP首部
tcpHeader.th_sport = htons(sourceport); //源端口
tcpHeader.th_dport = htons(portnow);//目的端口
tcpHeader.th_seq = htonl(0x12345678);
tcpHeader.th_ack = 0;
tcpHeader.th_lenres = (sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag = 2;//syn标志位。0,2,4,8,16,32->FIN,SYN,RST,PSH,ACK,URG
tcpHeader.th_win = htons(512);
tcpHeader.th_urp = 0;
tcpHeader.th_sum = 0;
//填充tcp伪首部
psdHeader.saddr = ipHeader.sourceIP;
psdHeader.daddr = ipHeader.destIP;
psdHeader.mbz = 0;
psdHeader.ptcl = IPPROTO_TCP;
psdHeader.tcpl = htons(sizeof(tcpHeader));
//计算TCP校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum = checksum((USHORT *)szSendBuf, sizeof(psdHeader) + sizeof(tcpHeader));
//计算IP检验和
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4);
ipHeader.checksum = checksum((USHORT *)szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
//发送数据包
ret = sendto(sendSocket, szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr*)&sin, sizeof(sin));
if(ret == SOCKET_ERROR)
{
printf("send error!:%x\n",WSAGetLastError());
return 0;
}
else return 1;
}
//SINFFER函数
int rec()
{
SOCKET SnifferSocket;
struct sockaddr_in sa;
char recvBuffer[65000] = {0};//缓冲区存放捕获的数据
//建立socket监听数据包
SnifferSocket = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
sa.sin_family = AF_INET;
sa.sin_port = htons(9999);
sa.sin_addr.s_addr = inet_addr(srcIP);
//绑定到本地端口 9999
bind(SnifferSocket,(struct sockaddr *)&sa,sizeof(sa));
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
//copy来的
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
WSAIoctl(
SnifferSocket,//套接字的描述符;
SIO_RCVALL,//待执行操作的控制代码,这里为SO_SSL_SET_VALIDATE_CERT_HOOK,表示将指针设置为证书验证指令;
&dwBufferInLen, //是一个指向输入缓冲区的指针;
sizeof(dwBufferInLen),//输入缓冲区大小;
&dwBufferLen, //指向输出缓冲区的指针;
sizeof(dwBufferLen),//输出缓冲区大小;
&dwBytesReturned ,//指向真实的输出字节的数值;
NULL , NULL //这里必须为NULL
);
while(1)
{
memset(recvBuffer , 0 , sizeof(recvBuffer) );
//开始捕获数据包
recv(SnifferSocket,recvBuffer,sizeof(recvBuffer),0);
check_port(recvBuffer); //调用解包函数
if(portnow>endscan)
break;
}
return 1;
}
请大家帮忙运行、测试,看有没有什么问题? |