www.pudn.com > PortScan_sjtu.rar > FinScan.cpp
// FinScan.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include#include #include "FinScan.h" #include "ws2tcpip.h" //#include "mstcpip.h" #pragma comment(lib,"ws2_32.lib") #define Port_Src 2233 #define SEQ 2315 USHORT FinScan::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 FinScan::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 = 1; // Fin = 2;ack = 0; means Fin 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)); //计算IP头校验和 ((IPV4_HDR *)&buf)->ip_checksum = ip_hdr.ip_checksum; ret = sendto(s, buf, sizeof(IPV4_HDR)+sizeof(TCP_HDR), 0, (struct sockaddr*) &dst_addr,sizeof(dst_addr)); //发送Fin报文 if (ret == SOCKET_ERROR) { sprintf(msg_buf,"Scan Port %d: Fin 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: Fin 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){ //是否RST包 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){ //ack位检测 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); } int main() { char result[500]; result[0] = '\0'; char* ip_dest = "192.168.1.5"; FinScan* test = new FinScan(); test->Scan(ip_dest,25,1000,result); std::cout<