www.pudn.com > PortScan_sjtu.rar > SYNScan.cpp
// SYNScan.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include#include #include "SYNScan.h" #include "ws2tcpip.h" #include "mstcpip.h" #pragma comment(lib,"ws2_32.lib") #define Port_Src 2233 #define SEQ 2315 USHORT SYNScan::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 SYNScan::Scan(char* IP_Dest, int Port_Dst, u_int time_out, char* msg) { char msg_buf[100]; WSADATA wsa; SOCKET s; char buf[256]; char recv_buf[256]; struct sockaddr_in src_addr,dst_addr; int ret = WSAStartup(MAKEWORD(2,2), &wsa); s = socket(AF_INET , SOCK_RAW , IPPROTO_IP); int flag = 1; ret = setsockopt(s, IPPROTO_IP,IP_HDRINCL ,(char *)&flag, sizeof(flag)); //socket选项,手动定义IP头 if (ret==SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: setopt:syn Error %d\r\n", Port_Dst,WSAGetLastError()); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&time_out, sizeof(time_out)); if (ret==SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: 无法设置套接字的接受超时时间!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&time_out, sizeof(time_out)); if (ret==SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: 无法设置套接字的发送超时时间!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } dst_addr.sin_family = AF_INET; dst_addr.sin_port = htons(Port_Dst); dst_addr.sin_addr.s_addr = inet_addr(IP_Dest); char host_name[100]; //取得主机地址 gethostname(host_name, sizeof(host_name)-1); LPHOSTENT host = gethostbyname(host_name); src_addr.sin_addr = *(in_addr *)host->h_addr; IPV4_HDR ip_hdr; //IP头设置 ip_hdr.ip_verlen = (4<<4 | sizeof(IPV4_HDR)/sizeof(unsigned long)); ip_hdr.ip_tos = 0; ip_hdr.ip_totallength = htons(sizeof(IPV4_HDR)+sizeof(TCP_HDR)); ip_hdr.ip_id = 1; ip_hdr.ip_offset = 0; ip_hdr.ip_ttl = 128; ip_hdr.ip_protocol = IPPROTO_TCP; ip_hdr.ip_checksum = 0; ip_hdr.ip_srcaddr = src_addr.sin_addr.s_addr; ip_hdr.ip_destaddr = inet_addr(IP_Dest); TCP_HDR tcp_hdr; //Tcp头设置 tcp_hdr.th_sport = htons(Port_Src); tcp_hdr.th_dport = htons(Port_Dst); tcp_hdr.th_seq = htonl(SEQ); tcp_hdr.th_ack = 0; tcp_hdr.th_lenres= (sizeof(TCP_HDR)/4<<4|0); tcp_hdr.th_flag = 2; // SYN = 2;ack = 0; means SYN scan tcp_hdr.th_win = htonl(512); tcp_hdr.th_checksum = 0; tcp_hdr.th_urp = 0; IP_PSD_HDR psd_hdr; //伪IP头设置 psd_hdr.src_addr = src_addr.sin_addr.s_addr; psd_hdr.dest_addr = inet_addr(IP_Dest); psd_hdr.mbz = 0; psd_hdr.protocol = IPPROTO_TCP; psd_hdr.tcplength = htons(sizeof(TCP_HDR)); memcpy(buf, &psd_hdr, sizeof(IP_PSD_HDR)); memcpy(buf + sizeof(IP_PSD_HDR), &tcp_hdr, sizeof(TCP_HDR)); tcp_hdr.th_checksum = checksum((u_short *)buf, sizeof(IP_PSD_HDR)+sizeof(TCP_HDR)); //计算Tcp头校验和 memcpy(buf, &ip_hdr, sizeof(IPV4_HDR)); memcpy(buf + sizeof(IPV4_HDR), &tcp_hdr, sizeof(TCP_HDR)); memset(buf + sizeof(IPV4_HDR) + sizeof(TCP_HDR), 0, 4); ip_hdr.ip_checksum = checksum((u_short *)buf, sizeof(IPV4_HDR)+sizeof(TCP_HDR)); ((IPV4_HDR *)&buf)->ip_checksum = ip_hdr.ip_checksum; //计算IP头校验和 ret = sendto(s, buf, sizeof(IPV4_HDR)+sizeof(TCP_HDR), 0, (struct sockaddr*) &dst_addr,sizeof(dst_addr)); //发送Syn包 if (ret == SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: Syn send error %d!\r\n",Port_Dst,WSAGetLastError()); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } int src_len = sizeof(src_addr); ret = recvfrom(s, (char *)&recv_buf, sizeof(recv_buf), 0, (SOCKADDR *)&src_addr, &src_len); //接受回复 if (ret==SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: Syn Reply recv error %d!\r\n",Port_Dst,WSAGetLastError()); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } int recv_len = ret; //回复包分析 if (recv_len < sizeof(IPV4_HDR)){ sprintf(msg_buf,"Scan Port %d: Syn Reply IPHEADER error!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return (-1); } IPV4_HDR *ip_hdr_recv = (IPV4_HDR *)recv_buf; //回复报文IP头分析 int ip_hdr_recv_len = ip_hdr_recv->ip_verlen & 0x0F; ip_hdr_recv_len = (ip_hdr_recv_len) << 2; if (checksum((u_short *)ip_hdr_recv, ip_hdr_recv_len)) { sprintf(msg_buf,"Scan Port %d: Syn Reply checksum error!\r\n",Port_Dst); strcat(msg,msg_buf); WSACleanup(); return(-1); } if (recv_len < (ip_hdr_recv_len + sizeof(TCP_HDR))) { //校验和 sprintf(msg_buf,"Scan Port %d: Syn Reply TCPHEADER recv error!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return(-1); } TCP_HDR *tcp_hdr_recv = (TCP_HDR *) (recv_buf + ip_hdr_recv_len); //回复报文TCP头分析 if ((tcp_hdr_recv->th_flag & 0x04) > 0){ sprintf(msg_buf,"Scan Port %d: Syn connect is rejected!\r\n",Port_Dst); strcat(msg,msg_buf); WSACleanup(); return(-1); } if ((tcp_hdr_recv->th_flag & 0x10) == 0){ //标志位 sprintf(msg_buf,"Scan Port %d: Syn reply ack error!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return(-1); } if (ntohl(tcp_hdr_recv->th_ack) != (SEQ+1) ){ //是否对刚发出去的报文的ack sprintf(msg_buf,"Scan Port %d: Syn reply ack sequence error!\r\n",Port_Dst); strcat(msg,msg_buf); closesocket(s); WSACleanup(); return(-1); } sprintf(msg_buf,"Scan Port %d: Syn scan succeed!\r\n",Port_Dst); strcat(msg,msg_buf); WSACleanup(); return (0); }