###################################################################### Luigi Auriemma Applications: Unreal engine This is the list of the vulnerable games: - America's Army - DeusEx - Mobile Forces - Nerf Arena Blast - Rune - Sephiroth: 3rd episode the Crusade - Star Trek: Klingon Honor Guard - Tactical Ops - TNN Pro Hunter - Unreal 1 - Unreal Tournament <= 436 - Unreal Tournament 2003 <= 2166 - Wheel of Time - X-com Enforcer Versions: All the 3 versions of the Unreal engine released until now (check each game for see if it has been patched!) Platforms: All the platforms supported: - Win32 - Linux - MacOS Bugs: A lot of problems (see "Bugs section") caused by the absence of a handshake between client and server plus other bugs like negative sign bug in index numbers and non-existant check of the keys generated for each match Date: 05 Feb 2003 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ###################################################################### 1) Introduction 2) Bugs quick resume (recommended) 3) Bugs/effects (technical details): - A] Generic DoS and DDoS problems with empty spoofed UDP packets - A-1] A DoS versus the same Unreal server - A-2] Distributed Denial of Service attack - B] Resources "lunch" and remote crash - C] Server filled by fake players - D] Bouncing bouncing - E] Code execution through package files - F] unreal:// crash 4) The Code 5) Fix ###################################################################### =============== 1) Introduction =============== The Unreal engine was born in 1998 and until now has evolved to give the maximum performance with the current hardware and it has been ported on a lot of systems, the last is the XBox console with Unreal Championship (really a phenomenal game!). Now it is the most diffused game engine in the videogames' history and it has been used for every type of games, from First Person Shooters to pinball games. This engine is now divided into 4 big releases that are: - Original build (first release): 226f --> 220 - Tournament build (second release): 220-224 --> 300-436 - Championship build (third release): 436 --> ??? - Warfare build (fourth release): not available at the moment (thanks to http://wiki.beyondunreal.com/wiki for these info) This engine is used by a lot of videogames companies as a "skeleton" for their games and the list of them is quite long. You can see the vulnerable games in the Applications header at the top of this advisory/paper. This was also the case as seen in recent weeks with Mike Kristovich's MK001 advisory which shed light on DDoS vulnerabilities within many games as seen here: http://www.pivx.com/kristovich/adv/mk001/ In this case the handshake lacking 'skeleton' was distributed to game vendors for widespread implementation Gamespy. The evolution of the engine contains graphic and sound improvements, new movements simulation (karma engine), newly supported APIs and many other optimizations. However there is a section of the engine that has not been optimized along with the other parts of the engine: the network protocol. The network protocol in Unreal engine has a lot of problems as you can see. The base of almost all the vulnerabilities within is the absence of a true handshake between the client and the server. The other problem, and I think the most dangerous, is that the Unreal engine has problems managing numbers with a negative sign (read point B and E in Bugs section for details about) and this problem result in resources consumption and code execution. The most frightening thing imaginable is that these bugs have been around for 5 years they could be used by malicious attackers in worms or attacks that rival those of Sapphire/Slammer and Nimda... Really frightful. The "story" of my research with the Unreal engine is very simple: when UnrealTournament 2003 demo was released in late 2002 I decided to see if Epic (Epic Games) had introduced a handshake or had made some changes in the network protocol to avoid the DoS and DDoS problem I had found in the previous versions of Unreal Tournament (http://aluigi.org/adv/ut-adv.txt)... but I found no changes present. So I began testing for other vulnerabilities in the Unreal network protocol and especially to better understand the details of this implemented engine. The result of my research is this paper. Have fun! ###################################################################### ==================== 2) Bugs quick resume ==================== 1] Unreal engine doesn't have an handshake between client and server, so an attacker can create DoS, DDoS and bounce attacks with spoofed UDP packets. 2] Unreal engine uses challenge keys to identify each match but, I don't know why, seems that the server doesn't really manage the keys in the client's answers and furthermore it doesn't make other checks to avoid an attacker easily adding faked players to the server. 3] The Unreal engine has problems managing negative long numbers (used for specify the size of data). - If an attacker use negative numbers in network packets, the Unreal server will allocate an amount of RAM that is equal to the number without the sign or crash if the amount of bytes is greater than the available memory. - If the attacker uses package files (the maps for example) he can easily execute code on the machine that launch the file, because the bug used in package file allows the attacker to overwrite the EIP register and upload all his code (no size limitations) in memory. 4] Problems with Unreal URLs (unreal://...) ###################################################################### =================================== 3) Bugs/effects (technical details) =================================== As I have said in the introduction, 3 releases exist relating to the Unreal engine at the moment (beginning of the 2003), the last of which starts with the release of UnrealTournament 2003 game so when I talk about UT2003, consider it like a generic referrer to the Unreal engine or simply a real practical example. ALL the releases of the engine are vulnerable to the bugs I have found because the network protocol and part of the core have not been modified at all from the far first release of the engine. Naturally "some" of my exploits can't run on all the versions of the engine or on other games because I have concentrated my tests on UT2003 (don't worry only a couple of my exploits must be modified a bit for a specific game or engine release). Relax yourself and let me to explain the details of the problems I have found: --------------------------------------------------------------- A] Generic DoS and DDoS problems with empty spoofed UDP packets --------------------------------------------------------------- If you try to send only one UDP packet to the game port of UnrealTournament 2003 server (default 7777) you will start to receive 4 or 5 packets per second from this server. The default timeout for these packets is 200 seconds (50 seconds more than the previous UT timeout, caused by loading times more long). If you watch in the console of the UT2003 server when the client sends the UDP packet you will see a string like the following: - NotifyAcceptingConnection: Server myLevel accept Open myLevel 11/10/02 09:56:08 192.168.0.3:32768 - Wonderful the server has accepted a connection with only one simple, empty UDP datagram 8-) In fact the real problem is that there is no handshake present for management of any real connections, and we must remember that the handshake is used by all the multiplayer games in the world; QuakeIII, Half-Life, etc... are only an example (ok Half-life has a bug in the handshake but at least it is implemented and then again nobody is perfect...) After the 200 seconds of timeout, finally the server stops it's little flooding spree and will display the following message in the UT2003 console: - Connection timed out after 200.000000 seconds (200.049645) Close TcpipConnection 11/10/02 09:59:28 - The consequences of this problem are essentially two fold: -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ A-1] A DoS versus the same Unreal server -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ Yes, all we need is to send UDP packets from the same server to itself, with a source port that is different for each packet (sequential or random for example) and with the standard game port used by the game as destination port. Example: 1.2.3.4:1 --> 1.2.3.4:7777 1.2.3.4:2 --> 1.2.3.4:7777 ... 1.2.3.4:65535 --> 1.2.3.4:7777 After a large amount of these datagrams the server will start to go very slow, so slow that is impossible to play. The PentiumII at 448Mhz machine that I used for these tests only displayed 1 frame per every 3 to 4 seconds, which is an astoundingly slow 0.25Fps!!! These interesting effects on the system used as a victim of the attack are as follows: System: Pentium II 448 Mhz (112 FSB x 4.0) Packets used: 1000 Ram utilization: 17 Mb (RAM during attack - RAM before attack) CPU utilization: 40% (CPU during attack - CPU before attack) Are you ready to see your new AthlonXP run like a 486? 8-) -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- A-2] Distributed Denial of Service attack -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- I think that everyone has an understanding of how dangerous each UT2003 server can be if an attacker utilizes thousands of very powerful servers on high speed internet connections to create a DDoS net. This risk would to use any amount of the UT2003 server "network" for launching devastating DDoS attacks. Naturally this attack is very very very simple. The attacker doesn't need to install DDoS tools on cracked servers or create a custom worm and wait for it to propagate. An attacker can found a list of servers of games based on Unreal engine anywhere! In fact if you point your browser to the following URLs you will see a real-time updated list of current UT2003 servers for full and demo games: http://ut2003master.epicgames.com/serverlist/full-all.txt http://ut2003master.epicgames.com/serverlist/demo-all.txt Furthermore you will found more servers in the Master servers used by Gamespy. (there are so much lists of servers that probably you will find them on Corn-flakes boxes as well 8-) Another purpose of this attack, other than totally block a host, is that some Internet users pay the connection to the Net about the network traffic and this can be an hard hit for their wallet. ------------------------------------- B] Resources "lunch" and remote crash ------------------------------------- The most interesting bug I have found in my research is the following. A specially formatted packet crash immediately EVERY server that uses Unreal engine: ALL the versions are vulnerable to the same packet! Let me start to explain a bit of Unreal engine basis: Unreal engine uses a method (a bit crazy) so to use less space in files and in network packets. This method is called "index type" or "Compact Indices" and is a long type number (31 bits + 1 bit for the sign) that is saved in a amount of bytes that can go from 1 to 5 (a long type number is 4 bytes, so this method is good for small values). In every packet sent through the network, before the data there is one of this index type numbers that specify the size of the data after it. Within each packet can exist many data "parts" and this index value is used for specify how many long is the current piece of data. Example: [index1][data1][index2][data2]...[indexN][dataN] The Unreal engine first decodes the packet and then simply reads the index number and finally allocate that size in memory. However seems that the Unreal engine makes a check for this index number for avoid possible abuses if an attacker try to set a big index number (something like: "if(index_number > packet_or_file_size) break;"), but unfortunately it sucks when the sign of this value is negative because the Unreal engine consider negative numbers as Unicode format that needs 2 bytes for each char. Example: If I want that the remote server allocates 512 Mb of RAM for read my packet, I must not use 512000000 (and naturally convert it in index format) but I must use -256000000 (negative sign plus half amount of data). Simple and funny. The maximum bytes of memory that we can allocate is a long type number so 0xffffffff less the first left bit that is used for the sign: 2147483647 bytes. The effects of this attack are really incredible: - if the size of the bytes to allocate is less than the maximum available memory on the remote system, the CPU will rise to 100% and will be consumed all the bytes of memory specified by the attacker. This effect will persist for a variable amount of time that depend by the size of the bytes that must be allocated and the performance of the victim machine (CPU and memory speed). For example my PII @ 448 Mhz takes 25 seconds to allocate 250 Megabytes in memory (with the UCC.EXE server, without the other weight of graphic, sound and artificial intelligence of the game). During this time seems that the server cannot manage Unreal packets. If you aren't running a dedicated server but you are playing on your same server, the game will freeze totally for a variable amount of seconds. - if the memory that must be allocated is superior than the available, the server will crash immediately! This attack is the fastest way to crash, freeze or consume memory of EVERY game server based on Unreal technology and naturally is the most secure if the attacker uses spoofed packets. As you can imagine, with a simple list of games from an above server-list, one black hatter could take down every one of those servers within a matter of seconds or simply freeze them for how much time he wants. -------------------------------- C] Server filled by fake players -------------------------------- A classic of games' bugs is to make join new players in a server but with a little difference... the players don't exist in reality 8-) Like a bug I previously found and published on Half-Life (http://aluigi.org/fakep.htm) only for matches that don't support WON authentification) the Unreal engine is vulnerable to a similar attack, but here is more simple and easily executed than Half-life attack. Incredibly the Unreal engine not only lacks a true handshake but the challenge key (the key created for each match and avoid abuses) is not considered by the server, so the attacker can use the same key or use a randomly generated key. So what this mean??? Simple, the packets that are sent by a player to a server to join a match (game) can be the SAME every time so an attacker can use every time the same UDP packets for join without know the network protocol or reversing the dec/encoding algorithm. And not only that, the attacker can spoof the UDP packets without problems because he doesn't need any challenge key, so he/she doesn't need to see the server answer. These "handshake packets" are generally 4 UDP datagrams that contain the following info: 1) Hello message with client version 2) Information about us like netspeed, username, password, class, character, team, the challenge key (unuseful) and other info 3) First part of files checksum (I think they are the checksum of the files in the package files or something similar) 4) Second part of files checksum + Join string The effect of this attack is simple: human players cannot join in a server under this type of attack because it is full. (Press F1 during the attack for see all the fake players) A very interesting feauture that I have seen in UT2003 is that these fake players cannot be seen by an external player that watch the info of the server because Unreal server doesn't show them in the list of current players in game (For example in UT2003 we will see 0/32 current players in the match, but if we try to join, the server will answer with server full message). Basically the server seems empty from outside but it is full of nonexistent players, and will stay that way until the attacker decides to cease the attack. -------------------- D] Bouncing bouncing -------------------- Another interesting attack that can be made versus the Unreal engine is the "bounce" because the network protocol let an attacker to use Unreal servers like a ping-pong game; the UDP packets can be bounced from a server to another or simply to the same server in an infinite loop. The only difference between games based on the Unreal engine can be the vulnerable port used by the game. For example the data port of UT2003 (default 7777) doesn't manage the same packet that comes from a previously managed source port and IP. So here we must use ping and info port for ping-pong (7778 and 10777). Instead UnrealTournament doesn't look at the source port so we can also use the data port (7777). I want only to add that this attack is very interesting for the attacker because he/she doesn't need to make a UDP flood or spend a lot of his/her network bandwidth, he needs only 1 UDP datagram... very funny! The maximum traffic reached on my loopback device is 5500 packets per second with only 1 packet sent... uhmm... not bad if we think that the game was emulated with Wine under Linux on an Athlon XP1800+... --------------------------------------- E] Code execution through package files --------------------------------------- This is the last but the most dangerous bug I have found during my research, not only because an attacker can execute code on the victim system, but especially because both single players and multiplayers matches are vulnerable. In fact ALL the games that use Unreal engine are vulnerable because this is not a bug about the network layer that some of these games don't use, but it is a problem of the engine's core (so the list at the top of my advisory can be more long). The problem is in the reading of package files. A full description of the format of the package files has been written by Antonio Cordero and is called "UT Package File format" http://www.acordero.org Very quickly, package file is the format used by the Unreal engine for read and store data like music, textures, maps, sound and any other type of data. In each package file there are 3 sections: name, import and export. The following structure is referred to the name section (that seems to be the only vulnerable to this bug): - index type: length of the name string (final NULL byte included) - char *name: the name string ("None\0" or "LevelInfo\0" for example) - u_long: flags An example of name sections is: "\x05None\x00\x10\x04\x07" that is used in almost all the package files of each game, and we can see the byte 0x05 that is referred to the "None\x00" string. The problem happen if an attacker modify this "length value" with one that have a negative sign (-512 instead of 512). For have more information about index type take a look at the bug [B] or read Cordero's "UT Package File format" at Index type section. The games based on Unreal engine will start to read a defined length of data in the file (24512 bytes in my ut-ucc436 exploit) but then it will has problem to manage this malformed "length value". The following is an example using the UnrealTournament entry.unr map file as a base of our attack and on a Win98 system where run UnrealTournament v436 (UCC.EXE in this example): At offset 0x00000040 we found the index_number that is used for specify the lenght of the "None\0" string that naturally is 5. So, instead of write "\x05None\0" (5 + "None\0" string) I write "\xffNone\0"; now the server will read it as 0xff4e (remember that it is an index type number equal to -5055) + the "one\0" string. The negative sign bug is alive and this time it will give us a lot of fun 8-) The EIP register will be overwritten by the DWORD at offset 0x000000fe and (on my systems) ALL the bytes that start from offset 0x0000004c to 0x0000066f will go in the stack starting at position 0x006493e0 (ESP + 0x2424). So an attacker can really uses a huge space that can be defined to himself!!! The following is a quick resume about the offsets of the code in memory and in the map file: --- String used = "\xffNone\0" Offset of EIP and ESP registers: EIP in memory = 0x04001000 offset of EIP in the file = 0x000000fe ESP = 0x006493e0 First part of the map file that will be placed in memory ("one\0\x10\x04\x07\x04..."): In memory = from> ESP + 2424 -to-> ESP + 24e0 In the file = from> 0x00000042 -to-> 0x000000fd Second part of the map file that will go in memory ("ayer\0\x10\x04..."): In memory = from> ESP + 24e8 -to-> ESP + 2a50 In the file = from> 0x00000106 -to-> 0x00000066f --- Note: if you want to create a map file to execute code, I suggest you to put your shellcode in the second part of the map file!!! Last dangerous thing is that the package files can be easily distributed because nobody (that is not a bug researcher or a paranoiac guy) have the suspect about a map file or a simple new texture or sound for his preferred game. How many map files have you happily downloaded fom your favorite game without thinking about the propagation of personal information, remote access to your system or worse, hardware or software damage? The only limit for an attacker is that hacked package files cannot be distributed via UCC servers and then sent to the client because, naturally, the server will crash when it reads them. 8-) (furthermore you cannot use first the original package file and then replace it with the hacked file because your server will refuses to send the map to the client, but I don't know why...). ------------------ F] unreal:// crash ------------------ After over two months from the signal given to Epic of the first problem I have found this new problems. The first problem is in the "Unreal URL" unreal:// because a host string too long will cause a crash in the game. The bug seems to be caused by Msvcrt.dll and the effect is the possibility of an attacker to overwrite a part of the EIP register. Fortunately for the gamers the string/host after unreal:// is stored in memory as a sequence of WORD and not as char, so the EIP can be overwritten only with "\x00 char2 \x00 char1", so I think that is really hard (or impossible) to execute code on the victim with this bug. The example Unreal URL for Unreal Tournament is the following: unreal://(261 chars)[EIP_byte][EIP_byte] So "unreal://(261 of 'z')ut" will overwrite the EIP with 0x00740075. An idea of the usage of this URL is on IRC versus the Unreal IRC client (used for example in Unreal Tournament) that will crash when the user will make a single click on the URL. Just FYI the unreal:// URL is vulnerable to a directory traversal bug that is not dangerous in this case but can give problems if the victim has a "normal" file in his system (a file that is not a package file, like an empty file for example) without extension that can be easily launched through unreal://file (or unreal://\directory\file if you wanna use the directory traversal bug) because the game try to search it in its directories for the file specified by the attacker and then plus the extensions of maps, textures, sounds and musics files. The effect for a empty file is the instantaneous crash of the game. However IMHO these 2 problems are a bit difficult to use and the effects are limited to a DoS. ###################################################################### =========== 4) The Code =========== I have written and released a lot of code to test the problems I have described in this paper and their effects. At the moment I have based my code on UT2003 game (that is the third release of the Unreal engine) but almost all the proof-of-concept run on other games and versions too. Most of if not all the code can be compiled on Win32 systems too (where spoofing is not necessary because I want that all the Win32 systems can use the programs, Win9x systems too). -------------------------------------------------------------- A] Generic DoS and DDoS problem with empty spoofed UDP packets -------------------------------------------------------------- -_-_-_-_-_--_-_-_-_-_- A-1] Unreal engine DoS -_-_-_-_-_--_-_-_-_-_- The first tool I show is designed for launching a DoS versus the same Unreal server and I have called it "Unreal engine loopback DoS" and it can be compiled only for Linux. With it you will test better how much slower your new PC/server will run during an attack: http://aluigi.org/poc/unrdos.c (the timeout value is UT2003 timeout, so remember to change it if you want to test other games!) -_-_-_-_-_-_-_-_-_- A-2] Full DDoS tool -_-_-_-_-_-_-_-_-_- The most important tool that I have written is UTDDoS. The new version on my personal web page now supports UT2003 servers as well as the UT servers. (You need at least Libnet 1.1.0 and Linux to compile it: http://www.packetfactory.net/libnet) http://aluigi.org/poc/utddos.c ------------------------------------- B] Resources "lunch" and remote crash ------------------------------------- For ALL the games. (code for both Linux and Win32 systems) http://aluigi.org/poc/unrcrash.zip -------------------------------- C] Server filled by fake players -------------------------------- UT2003 specific (I have tested the DEMO game only!). Change the strings in the #define for run it on other games. (Can be compiled on both Linux and Win32 systems): http://aluigi.org/fakep/ut2003fake.zip -------------------- D] Bouncing bouncing -------------------- UT2003 specific. Change the #define for run it on other games. (must be compiled on Linux): http://aluigi.org/poc/ut2003bounce.c --------------------------------------- E] Code execution through package files --------------------------------------- The most technical exploit in the "collection"... Proof-of-concept map file for UnrealTounament v436 for Win98 ONLY is here: http://aluigi.org/poc/ut436.unr.zip In the zip there are a map file that must be used with UCC server (ut-ucc436.unr) and another that must be used with the game (DM-ut436.unr). The first will display a message in the console and then will exit. The second map file will display a MessageBox and then will exit (on some machine can happen that the MessageBox need some seconds before spawn) Both the map files can run only on Win98 systems. --- I have also written a simple checker for package files of every game based on the Unreal engine: http://aluigi.org/papers/unrcheck.zip ------------------ F] unreal:// crash ------------------ unreal://(261 chars)[EIP_byte2][EIP_byte1] or unreal://(258 chars) unreal://\directory\file or any other modification as unreal://..\..\directory\file --------------------------------------------------------------------- UDP Sniffer + Unreal engine packet decoder + encoder (experimentals!) --------------------------------------------------------------------- I have also written a simple UDP sniffer for private use that is able to decode a great part of the Unreal network traffic, so I have thought that can be useful for other people too. The program run on both Linux and Win32 systems (Win32 need Winpcap and you can found it at http://www.winpcap.org) http://aluigi.org/papers/unrsniff.zip --- The stand-alone decoder and the encoder can be downloaded here: http://aluigi.org/papers/unrenc.zip http://aluigi.org/papers/unrdec.zip NOTE: - As I have said in the header, these applications are experimentals because I have not reversed all the complete algorithm, but I use some workarounds for read packets. However the only interesting packets are the first 4 or 5 packets of each connection because they contain interesting data about the procedure for join a match and a lot of information about client and server. - The first 2 bytes of each packet are the "packet number" but I prefer to decode/encode ALL the bytes in packets (these bytes as well). ###################################################################### ====== 5) Fix ====== All the latest patches are availables at http://www.unrealtournament2003.com I have written a simple checker for package files of every game based on the Unreal engine (for avoid the bug 'E'): http://aluigi.org/papers/unrcheck.zip ######################################################################