####################################################################### Luigi Auriemma Application: Roger Wilco (http://www.rogerwilco.com) Versions: Mk.1d3 dated 14th Sep 2001 (1.4.1.2 is NOT vulnerable) Platforms: Windows Bugs: RogerWilco doesn't check the length of the nicknames sent by the clients and exists also a problem in a recv() function Date: 02 Jul 2003 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduction =============== Roger Wilco is probably the most famous tool that lets gamers to speak together during the matches with their preferred games. It is shareware and is developed by Gamespy. ####################################################################### ======= 2) Bugs ======= The 2 bugs I have found affect ONLY the main graphical program (roger.exe), NOT the dedicated server: ----------------------------- [A] Broadcast buffer overflow ----------------------------- This bug is just the perfect situation to make tons of damage using the minumum energy. Until now I have never found a "broadcast" buffer overflow, so I'm very interested about. This buffer overflow happens when a client that connects to the server sends a nickname string too long (a classical BoF...). The nickname must be at least 516 bytes long to overwrite the return address of EVERY client that receive this nickname. In fact the server (both normal and dedicated server) will send the nickname field in broadcast to ALL the clients connected to it. That mean that ALL the clients connected to the server (the graphical program become both server and client when hosts a channel) will execute the malicious code in the nickname field sent by the attacker! Now a bit of assembly for who is interested in the details: The vulnerable function starts at offset 0x40a1b0 of roger.exe The instructions that cause the overwriting of the return address are the following: :0040A200 8BF7 mov esi, edi :0040A202 8B7C2414 mov edi, dword ptr [esp+14] :0040A206 C1E902 shr ecx, 02 :0040A209 F3A5 repz movsd :0040A200 ESI will point to the beginning of the nickname sent by the client ("aaaaaaaaaaaaaaaaaaaaaa...") :0040A202 now the address of the destination buffer will be copied into EDI register :0040A206 the size of the data will be divided for 4 (it copies 32 bits each time) :0040A209 it copies the bytes that starts at the address pointed by ESI to the new buffer overwriting the return address stored at offset 0x0068f080 (the right return address stored before the BoF was 0x00409304) When RogerWilco executes the instruction at offset 0x0040A209 the return address stored at offset 0x0068f080 will be fully overwritten. ----------------- [B] Server freeze ----------------- A client can connect to the server that hosts a channel and instead of sending a full packet it sends it partially. The "join-packet" contains all the data of the client as the channel it wants to join to, the password for the channel, its nickname and some other little informations. The problem happens when the client uses the nickname tag ("\x0f\x10") BUT doesn't complete the packet with all the other needed informations. An example is the following packet: "\x0f\x00" "\x00\x14" "\x6a\xd6\x4c\x03\x96\xed\x3b\xe7\x88\xe2\xa9\x74" "channel\0" "\x0f\x10" <-- here there is nothing! As you can see there is nothing after the nickname tag. The problem happens in NETWORK.DLL when the program calls the function WSOCK32.recv: --- :100027B1 51 push ecx * Reference To: WSOCK32.recv, Ord:0010h | :100027B2 E8BF440000 Call 10006C76 :100027B7 CC int 03 --- In fact the recv() function will NOT return until the malicious client is connected to the server (probably because it waits the other pieces of data that the attacker has not sent). When the attacker will disconnect itself, the situation will return normally. ####################################################################### =========== 3) The Code =========== I have written a program that tests the 2 bugs I have found. You can choose your nickname, the channel to join, the relative password to use, the port to connect to, using the autorejoin option (so you can rejoin infinitely), getting remote informations and naturally you can also see what happens in realtime on the server, as who enters, who exits, relative IP addresses, who changes his nickname and other little informations. Naturally, as almost all my tools, it can be compiled on both Unix and Windows: http://aluigi.org/poc/wilco.zip ####################################################################### ====== 4) Fix ====== RogerWilco supports the autoupdate feauture so you should already have the patched version, however the latest (1.4.1.2) released 16th June 2003 is available on the official homepage: http://www.rogerwilco.com #######################################################################