####################################################################### Luigi Auriemma Application: Raydium http://raydium.org Versions: <= SVN revision 309 (newer versions can be vulnerable to some of the bugs which are still unfixed) Platforms: Windows, *nix, *BSD and others Bugs: A] buffer-overflow in raydium_log and raydium_console_line_add B] format string in raydium_log C] NULL function pointer in raydium_network_netcall_exec D] buffer-overflow and invalid memory access in raydium_network_read Exploitation: A] remote, versus server and client B] remote, versus server and client C] remote, versus server and client D] remote, versus client Date: 12 May 2006 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduction =============== Raydium is a complete open source game engine with multiplayer support and many other important and interesting features. ####################################################################### ======= 2) Bugs ======= -------------------------------------------------------------- A] buffer-overflow in raydium_log and raydium_console_line_add -------------------------------------------------------------- The logging function of Raydium is very used in all the engine. For example everytime a client tries to join the server it logs the event in the console: raydium_log("network: client %i connected as %s"/*,inet_ntoa(from->sin_addr)*/,n,name); This useful function is affected by a buffer-overflow bug where the local buffer str of 255 (RAYDIUM_MAX_NAME_LEN) bytes is filled using the unsecure sprintf function. The size of the input packet is 512 (RAYDIUM_NETWORK_PACKET_SIZE) bytes of which 508 are available for the text to use for exploiting the vulnerability. From raydium/log.c: // need to be secured void raydium_log(char *format, ...) { char str[RAYDIUM_MAX_NAME_LEN]; va_list argptr; va_start(argptr,format); vsprintf(str,format,argptr); va_end(argptr); printf("Raydium: %s\n",str); if(raydium_log_file) fprintf(raydium_log_file,"%s\n",str); raydium_console_line_add(str); } Similar thing for raydium_console_line_add: From raydium/console.c: // need to secure this one too void raydium_console_line_add(char *format, ...) { char str[RAYDIUM_MAX_NAME_LEN]; va_list argptr; va_start(argptr,format); vsprintf(str,format,argptr); va_end(argptr); raydium_console_line_last++; if(raydium_console_line_last>=RAYDIUM_CONSOLE_MAX_LINES) raydium_console_line_last=0; strcpy(raydium_console_lines[raydium_console_line_last],str); } ------------------------------- B] format string in raydium_log ------------------------------- The same raydium_log function described above is affected also by a format string vulnerability caused by the calling of raydium_console_line_add passing directly the text string without the required format argument: raydium_console_line_add(str); -------------------------------------------------------- C] NULL function pointer in raydium_network_netcall_exec -------------------------------------------------------- The function raydium_network_netcall_exec is called by raydium_network_read for selecting the specific function to use for handling the type of packet received. The raydium_network_netcall_type array is initialized with the type -1 so if the attacker uses the type 0xff the function will try to call raydium_network_netcall_func which is still initialized with a NULL pointer. The effect is the crash of the program. From raydium/network.c: ... for(i=0;i