第一个: //这是别人写的一个半连接的扫描 //
#include <winsock2.h> #include <ws2tcpip.h> #include "mstcpip.h" #include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
//////////////////////////////////////////////////////////////// //全局变量 ////////////////////////////////////////////////////////////////
#define srcPort 88
char srcIP[20] = ; //定义源地址 ----------->>>>>>> char tgtIP[20] = ; //定义目的地址 -------------->>>>>>> int portNow; //定义正在扫描的端口
//标准端口列表 int ports[20] =;
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 recv_packet(); //监听数据函数 USHORT checksum( USHORT *, int ); //计算检验和函数 void check_port( char * ); //判断端口是否开放函数
//////////////////////////////////////////////////////////////// ------------------------------ //main函数 ////////////////////////////////////////////////////////////////
int main( int argc , char *argv[] ) { int end; WSADATA WSAData; DWORD thread_ID = 1; char FAR hostname[128] = ; //--------->>>>>>>>>> HANDLE ThreadHandle[20]; struct hostent *phe;
if( argc != 2 )//检查命令行参数是否正确 { usage( argv[0] ); exit( 0 ); }
if ( WSAStartup(MAKEWORD(2,2) , &WSAData) ) { printf("WSAStartup Error...\n"); exit(0); }
strcpy(tgtIP,argv[1]);//得到目标主机的ip地址
gethostname(hostname,128);//获取本机主机名
phe = gethostbyname(hostname);//获取本机ip地址结构
if(phe == NULL) { printf("Get LocalIP Error...\n"); }
strcpy(srcIP, inet_ntoa(*((struct in_addr *)phe->h_addr_list[0])));//得到本机ip地址
//调试用,注释掉 //printf("test\t%s\n",tgtIP); //printf("test\t%s\n",srcIP);
//开启新线程,接受数据包,分析返回的信息 HANDLE RecvHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recv_packet,NULL,0,&thread_ID);
Sleep(500);//休息一下再启动发送数据包函数
for(int tmp = 0; tmp < 20; tmp++) { ++thread_ID;
//要扫描的端口 portNow = ports[tmp];
//开启新线程,发送数据包 ThreadHandle[tmp] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_packet,NULL,0,&thread_ID);
//防止生成线程过快,休息 Sleep(100); }
DWORD WaitThread = WaitForMultipleObjects( 20 , ThreadHandle , TRUE , INFINITE ); if( WaitThread != WAIT_FAILED) { for( int n = 0 ; n < 20 ; n++ ) { CloseHandle( ThreadHandle[n] ); } } CloseHandle( RecvHandle );
WSACleanup(); scanf("%d",&end); 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);
sin.sin_family = AF_INET; sin.sin_port = htons(portNow); sin.sin_addr.S_un.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_dport = htons(portNow);//目的端口 tcpHeader.th_sport = htons(srcPort); //源端口 tcpHeader.th_seq = 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 Packet Error...\n"); return 0; } else return 1; }
//SINFFER函数 int recv_packet() { SOCKET sock; SOCKADDR_IN sniff; char recvBuffer[65000] = {0};//缓冲区存放捕获的数据
//建立socket监听数据包 sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
sniff.sin_family = AF_INET; sniff.sin_port = htons(0); sniff.sin_addr.s_addr = inet_addr(srcIP);
//绑定到本地随机端口 bind(sock,(PSOCKADDR)&sniff,sizeof(sniff));
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包 //copy来的 DWORD dwBufferLen[10] ; DWORD dwBufferInLen = 1 ; DWORD dwBytesReturned = 0 ; WSAIoctl(sock,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
while(1) { memset(recvBuffer , 0 , sizeof(recvBuffer) );
//开始捕获数据包 int bytesRecived = recv(sock,recvBuffer,sizeof(recvBuffer),0); if(bytesRecived <= 0) { break; } check_port(recvBuffer); //调用解包函数 } return 1; }
//解包函数 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=0;tmp<20;tmp++) { //SYN+ACK -> 2+16=18(也是推测,哈哈) if(tcpHeader->th_flag == 18 && tcpHeader->th_sport == htons(ports[tmp])) { printf("[Found]\t%s\tport\t%d\tOpen\n",tgtIP,ports[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); } 第二个: //半打开扫描源程序(for WIN2K) #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include "mstcpip.h" #pragma comment(lib,"ws2_32")
#define DEFAULT_DEST_PORT 5 #define DEST_HOST "www.hrbust.edu.cn" #define SEQ 0x28376839
typedef struct _iphdr { unsigned char h_lenver; //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 _tcphdr //定义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;
struct //定义TCP伪首部 { unsigned long saddr; //源地址 unsigned long daddr; //目的地址 char mbz; char ptcl; //协议类型 unsigned short tcpl; //TCP长度 }psd_header;
SOCKET sockRaw = INVALID_SOCKET, sockListen = INVALID_SOCKET; struct sockaddr_in dest;
//SOCK错误处理程序 void CheckSockError(int iErrorCode, char *pErrorMsg) { if(iErrorCode==SOCKET_ERROR) { printf("%s Error:%d\n", pErrorMsg, GetLastError()); closesocket(sockRaw); ExitProcess(-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); }
//IP解包程序 bool DecodeIPHeader(char *buf, int bytes) { IP_HEADER *iphdr; TCP_HEADER *tcphdr; unsigned short iphdrlen;
iphdr = (IP_HEADER *)buf; iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf); tcphdr = (TCP_HEADER*)(buf + iphdrlen);
//是否来自目标IP if(iphdr->sourceIP != dest.sin_addr.s_addr) return false;
//序列号是否正确 if((ntohl(tcphdr->th_ack) != (SEQ+1)) && (ntohl(tcphdr->th_ack) != SEQ)) return false;
//RST/ACK - 无服务 if(tcphdr->th_flag == 20) { printf(".\n"); return true; }
//SYN/ACK - 扫描到一个端口 if(tcphdr ->th_flag == 18) { printf("%d\n",ntohs(tcphdr->th_sport)); return true; }
return true; }
//主函数 int main(int argc,char **argv) { int iErrorCode; int datasize; struct hostent *hp; IP_HEADER ip_header; TCP_HEADER tcp_header; char SendBuf[128]={0}; char RecvBuf[65535]={0};
//初始化SOCKET WSADATA wsaData; iErrorCode = WSAStartup(MAKEWORD(2,2),&wsaData); CheckSockError(iErrorCode, "WSAStartup()"); sockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP); CheckSockError(sockRaw, "socket()"); sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP); CheckSockError(sockListen, "socket");
//设置IP头操作选项 BOOL bOpt = true; iErrorCode = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt)); CheckSockError(iErrorCode, "setsockopt()");
//获得本地IP SOCKADDR_IN sa; unsigned char LocalName[256];
iErrorCode = gethostname((char*)LocalName,sizeof(LocalName)-1); CheckSockError(iErrorCode, "gethostname()"); if((hp = gethostbyname((char*)LocalName)) == NULL) { CheckSockError(SOCKET_ERROR, "gethostbyname()"); } memcpy(&sa.sin_addr.S_un.S_addr,hp->h_addr_list[0],hp->h_length); sa.sin_family = AF_INET; sa.sin_port = htons(7000); iErrorCode = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa)); CheckSockError(iErrorCode, "bind");
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包 DWORD dwBufferLen[10] ; DWORD dwBufferInLen = 1 ; DWORD dwBytesReturned = 0 ; iErrorCode=WSAIoctl(sockListen, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL ); CheckSockError(iErrorCode, "Ioctl");
//获得目标主机IP memset(&dest,0,sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(DEFAULT_DEST_PORT); if((dest.sin_addr.s_addr = inet_addr(DEST_HOST)) == INADDR_NONE) { if((hp = gethostbyname(DEST_HOST)) != NULL) { memcpy(&(dest.sin_addr),hp->h_addr_list[0],hp->h_length); dest.sin_family = hp->h_addrtype; printf("dest.sin_addr = %s\n",inet_ntoa(dest.sin_addr)); } else { CheckSockError(SOCKET_ERROR, "gethostbyname()"); } }
//填充IP首部 ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long)); //高四位IP版本号,低四位首部长度 ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位总长度(字节) ip_header.ident=1; //16位标识 ip_header.frag_and_flags=0; //3位标志位 ip_header.ttl=128; //8位生存时间TTL ip_header.proto=IPPROTO_TCP; //8位协议(TCP,UDP…) ip_header.checksum=0; //16位IP首部校验和 ip_header.sourceIP=sa.sin_addr.s_addr; //32位源IP地址 ip_header.destIP=dest.sin_addr.s_addr; //32位目的IP地址
//填充TCP首部 tcp_header.th_sport=htons(7000); //源端口号 tcp_header.th_dport=htons(DEFAULT_DEST_PORT); //目的端口号 tcp_header.th_seq=htonl(SEQ); //SYN序列号 tcp_header.th_ack=0; //ACK序列号置为0 tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0); //TCP长度和保留位 tcp_header.th_flag=2; //SYN 标志 tcp_header.th_win=htons(16384); //窗口大小 tcp_header.th_urp=0; //偏移 tcp_header.th_sum=0; //校验和
//填充TCP伪首部(用于计算校验和,并不真正发送) psd_header.saddr=ip_header.sourceIP; psd_header.daddr=ip_header.destIP; psd_header.mbz=0; psd_header.ptcl=IPPROTO_TCP; psd_header.tcpl=htons(sizeof(tcp_header));
//计算TCP校验和,计算校验和时需要包括TCP pseudo header memcpy(SendBuf,&psd_header,sizeof(psd_header)); memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header)); tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));
//计算IP校验和 memcpy(SendBuf,&ip_header,sizeof(ip_header)); memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header)); memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4); datasize=sizeof(ip_header)+sizeof(tcp_header); ip_header.checksum=checksum((USHORT *)SendBuf,datasize);
//填充发送缓冲区 memcpy(SendBuf,&ip_header,sizeof(ip_header));
//发送TCP报文 iErrorCode=sendto(sockRaw,SendBuf,datasize,0,(struct sockaddr*) &dest, sizeof(dest)); CheckSockError(iErrorCode, "sendto()");
//接收数据 DWORD timeout = 2000; DWORD start = GetTickCount(); while(true) { //计时,2s超时 if((GetTickCount() - start) >= timeout) break;
memset(RecvBuf, 0, sizeof(RecvBuf)); iErrorCode = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0); CheckSockError(iErrorCode, "recv");
if(DecodeIPHeader(RecvBuf,iErrorCode)) break; }
//退出前清理 if(sockRaw != INVALID_SOCKET) closesocket(sockRaw); WSACleanup(); return 0; } 
|