分享

简单实现SYN端口扫描

 waitingnothing 2018-07-17
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> #include<errno.h> #include <arpa/inet.h> #include <linux/tcp.h> #include<pthread.h> #include<fcntl.h> /* * Author:Exploit * 这是一个SYN极速扫描的demo * 存在的问题:发包的速度要控制 不然丢包很严重 * 但是在60个端口的范围内有效 * * */ //定义TCP伪报头 typedef struct psd_hdr { unsigned long saddr; //源地址 unsigned long daddr; //目的地址 char mbz; char ptcl; //协议类型 unsigned short tcpl; //TCP长度 }PSD_HEADER; //定义TCP报头 typedef struct _tcphdr { unsigned short th_sport; //16位源端口 unsigned short th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres; //4位首部长度/4位保留字 unsigned char th_flag; //6位标志位 unsigned short th_win; //16位窗口大小 unsigned short th_sum; //16位校验和 unsigned short th_urp; //16位紧急数据偏移量 } TCP_HEADER; //定义IP报头 typedef struct _iphdr { unsigned char h_lenver ; //长度加版本号 unsigned char tos; unsigned short total_len; unsigned short ident; unsigned short frag_and_flags; unsigned char ttl; unsigned char proto; unsigned short checksum; unsigned int sourceIP; unsigned int destIP; } IP_HEADER; /** * 计算校验和 */ unsigned short checksum(unsigned short *addr,int len){ int nleft=len; int sum=0; unsigned short * w=addr; unsigned short answer=0; while (nleft>1) { sum =*w ; nleft-=2; } if (nleft==1) { *(unsigned char *)(&answer)=*(unsigned char *)w; sum =answer; } sum=(sum>>16) (sum & 0xffff); sum =(sum>>16); answer=~sum; return(answer); } /* 攻击目标*/ struct sockaddr_in target; struct sockaddr_in myaddr; int sockfd ; pthread_t pth ; void TCP_Send(int port,unsigned char flag); void* recvpackage(void*arg) ; int main(int args,char* argv[]){ //参数检查 if(args < 4){ printf('Usage:shit targetIP startPort endPort\n') ; exit(-1) ; } char IP[32] ; //目标IP strcpy(IP,argv[1]) ; int startPort = atoi(argv[2]) ; int endPort = atoi(argv[3]) ; if((endPort - startPort) > 60){ printf('The port range must be within 60 considering your bandwith....\n') ; exit(-1) ; } target.sin_family = AF_INET ; target.sin_addr.s_addr = inet_addr(IP) ; myaddr.sin_family = AF_INET ; myaddr.sin_port = htons(60000) ; myaddr.sin_addr.s_addr = inet_addr('10.10.10.132') ; //TCP报文的socket sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP) ; if(sockfd == -1){ printf('socket error:%s\n',strerror(errno)) ; exit(-1) ; } int i ,count=1; for(i=startPort;i<endPort;i ){ TCP_Send(i,2); } pthread_create(&pth,NULL,recvpackage,NULL) ; pthread_join(pth,NULL) ; close(sockfd) ; return 0 ; } void TCP_Send(int port,unsigned char flag){ //设置目标端口 target.sin_port = htons(port) ; //构造包 char buffer[256] ; memset(buffer,0,256) ; struct _tcphdr tcpHeader ; struct psd_hdr psdHeader ; //填充TCP //目的端口 tcpHeader.th_dport = htons(port) ; //源端口 tcpHeader.th_sport = htons(60000) ; //序列号?? tcpHeader.th_seq = htonl(0x1245678); //确认号 tcpHeader.th_ack = 0; //(4位首部长度/4位保留字) tcpHeader.th_lenres = (sizeof(tcpHeader) / 4 << 4 | 0); //SYN标志 tcpHeader.th_flag = flag ;//SYN //滑动窗口 tcpHeader.th_win = htons(16384) ; //16位紧急数据偏移量 tcpHeader.th_urp = 0; //16位校验和 tcpHeader.th_sum = 0; //psdheader psdHeader.saddr = myaddr.sin_addr.s_addr; psdHeader.daddr = target.sin_addr.s_addr; psdHeader.mbz = 0; // mbz = must be zero, 用于填充对齐 psdHeader.ptcl = IPPROTO_TCP ; //8位协议号 psdHeader.tcpl = htons(sizeof(tcpHeader)) ; //set checksum 使用伪头计算TCP校验和 memcpy(buffer,&psdHeader,sizeof(psdHeader)) ; memcpy(buffer sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader)) ; tcpHeader.th_sum = checksum((unsigned short*)buffer,sizeof(psdHeader) sizeof(tcpHeader)) ; //最终的组包(TCP IP) memcpy(buffer,&tcpHeader,sizeof(tcpHeader)) ; //发送的过程 由于IP协议是无连接的协议 所以可以使用sendto int ret = sendto(sockfd,buffer,sizeof(tcpHeader),0,(struct sockaddr*)&target,sizeof(target)) ; if(ret == -1){ printf('send error!:%s\n',strerror(errno)) ; exit(-1); }else{ //printf('send OK\n') ; } } /* * 线程的回调函数 * */ void* recvpackage(void*arg){ //接收的过程recvfrom printf('Thread starting...\n') ; struct _tcphdr* testtcp ; char msg[1024] ; int len = sizeof(myaddr); int count ,size; while(1){ memset(msg,0,1024) ; size = recvfrom(sockfd,msg,sizeof(msg),0,(struct sockaddr*)&myaddr,&len) ; if (size == -1) break ; //这里的指针是指向IP头部第一个字段的 所以得到TCP头部时要加上相应的偏移量20byte testtcp = (struct _tcphdr*)(msg sizeof(struct _iphdr)) ; if (size < (20 20)){/*读出的数据小于两个头的最小长度的话continue*/ continue; } if(ntohs(testtcp->th_dport) != 60000){ continue ; } if(testtcp->th_flag == 20){ printf('%d 端口未开放\n',ntohs(testtcp->th_sport)) ; continue ; } if(testtcp->th_flag == 18){ TCP_Send(ntohs(testtcp->th_sport),4) ; printf('%d 端口开放!ACK SYN....\n',ntohs(testtcp->th_sport)) ; continue ; } } }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多