我已经编写了一个小工具,它只是抛出一个syn包在任何IP和端口号你给它 – 当我popupWireshark,发送的包看起来很好,没有错误或任何东西,它看起来就像你的典型的TCP SYN包。
由于某种原因,ACK不是由服务器发送的。 所以有两个问题。 一,没有应答。 二,我甚至不知道如何通过我的程序(bind()?)来接收ack响应。
我修改了我在网上find的syn flooder的一些代码,因为在我看来,一些script-kiddie代码很容易遵循,但是恐怕它可能会丢失一些东西,可能是服务器的ACK拒绝的结果。 代码已被修改,所以syn请求从合法的IP地址发送。 以下代码显示了我的ip + tcp头文件:
iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr); iph->id = htonl (54321); //Id of this packet iph->frag_off = 0; iph->ttl = 255; iph->protocol = 6; iph->check = 0; //Set to 0 before calculating checksum iph->saddr = 0; //Source ip filled in by kernel iph->daddr = sin.sin_addr.s_addr; //TCP Header tcph->source = htons (9999); tcph->dest = htons (atoi(argv[2])); tcph->seq = random (); // tcph->ack_seq = 0; tcph->doff = 5; /* first and only tcp segment */ tcph->syn = 1; tcph->window = htonl (65555); /* maximum allowed window size */ tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission */ tcph->urg_ptr = 0; //Now the IP checksum iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
所以,我发送了,没有回复。 我错过了什么?
该行:
tcph->window = htonl (65555);
可能会导致问题。 因为65555大于0xFFFF。 window
字段大小是16位。
所以这可能会更好:
tcph->window = htons (65535);
注意:htonl变成了htons。
编辑:
或者甚至更好(如果可用的话):
tcph->window = htons (TCP_MAXWIN);
问题也可能是缺乏TCP校验和计数。 您的代码假定较低层更新TCP校验和字段。 由于所有网络接口卡都不支持TCP校验和卸载 ,因此该代码可能无法在每台主机上运行。
你还没有写完整个代码。 有可能有地区,你会错过的东西。
这段代码将帮助你。
#include<stdio.h> #include<string.h> #include<sys/socket.h> #include<stdlib.h> #include<errno.h> #include<netinet/tcp.h> #include<netinet/ip.h> struct pseudo_header { u_int32_t source_address; u_int32_t dest_address; u_int8_t placeholder; u_int8_t protocol; u_int16_t tcp_length; }; unsigned short csum(unsigned short *ptr,int nbytes) { register long sum; unsigned short oddbyte; register short answer; sum=0; while(nbytes>1) { sum+=*ptr++; nbytes-=2; } if(nbytes==1) { oddbyte=0; *((u_char*)&oddbyte)=*(u_char*)ptr; sum+=oddbyte; } sum = (sum>>16)+(sum & 0xffff); sum = sum + (sum>>16); answer=(short)~sum; return(answer); } int main (void) { int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP); if(s == -1) { perror("Failed to create socket"); exit(1); } char datagram[4096] , source_ip[32] , *data , *pseudogram; char buffer[4096]; memset (datagram, 0, 4096); struct iphdr *iph = (struct iphdr *) datagram; struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct iphdr)); struct sockaddr_in sin; struct pseudo_header psh; data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr); strcpy(data , "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); strcpy(source_ip , "127.0.0.1"); sin.sin_family = AF_INET; sin.sin_port = htons(55559); sin.sin_addr.s_addr = inet_addr ("127.0.0.1"); iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data); iph->id = htonl (54351); iph->frag_off = 0; iph->ttl = 255; iph->protocol = IPPROTO_TCP; iph->check = 0; iph->saddr = inet_addr ( source_ip ); iph->daddr = sin.sin_addr.s_addr; iph->check = csum ((unsigned short *) datagram, iph->tot_len); tcph->source = htons (55554); tcph->dest = sin.sin_port; tcph->seq = htonl(4362); tcph->ack_seq = htonl(0); tcph->doff = 5; tcph->fin=0; tcph->syn=1; tcph->rst=0; tcph->psh=0; tcph->ack=0; tcph->urg=0; tcph->window = 1; tcph->check = 0; tcph->urg_ptr = 0; psh.source_address = inet_addr( source_ip ); psh.dest_address = sin.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) ); int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data); pseudogram = malloc(psize); memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header)); memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data)); tcph->check = csum( (unsigned short*) pseudogram , psize); int one = 1; const int *val = &one; if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { perror("Error setting IP_HDRINCL"); exit(0); } sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin)); return 0;
}