I received this mail from Luigi Auriemma (
http://aluigi.org , thanks to him) and he allows me to post it here.
Code:
Hey,
I want to report some security bugs I have found in the latest SVN
version of Raydium (tested revision 301):
--------------------------------------------------------------
A] buffer-overflow in raydium_log and raydium_console_line_add
--------------------------------------------------------------
The logging function of Raydium is very used in 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.
--------------------------------------------------------
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 problem is that the function pointer is not correctly initialized
(or assigned) if the type of packet received is major than the number
32 (RAYDIUM_NETWORK_MAX_NETCALLS), causing the crash of the program
during the calling of the resulted NULL pointer.
From raydium/network.c:
void raydium_network_netcall_exec(int type,char *buff)
{
char tmpbuff[RAYDIUM_NETWORK_PACKET_SIZE];
int i;
void (*f)(int, char*);
for(i=0;i<RAYDIUM_NETWORK_MAX_NETCALLS;i++)
if(raydium_network_netcall_type[i]==type)
{
memcpy(tmpbuff,buff,RAYDIUM_NETWORK_PACKET_SIZE);
f=raydium_network_netcall_func[i];
f(type,tmpbuff);
}
}
--------------------------------------------------------------------
D] buffer-overflow and invalid memory access in raydium_network_read
--------------------------------------------------------------------
The function raydium_network_read is affectd by some buffer-overflow
bugs which happens during the writing of some global variables
allocated in an array of 32 (RAYDIUM_NETWORK_MAX_SERVERS) elements.
The same function is also affected by an invalid memory access could
happen when the server sends a packet to the client containing an 8
bit id bigger than 8 (RAYDIUM_NETWORK_MAX_CLIENTS).
Both the bugs can be exploited only versus the clients.
>From raydium/network.c:
signed char raydium_network_read(int *id, signed char *type, char *buff)
...
strcpy(raydium_network_server_list[slot].name,name);
...
strcpy(raydium_network_server_list[slot].info,info);
...
i=buff[RAYDIUM_NETWORK_PACKET_OFFSET];
strcpy(raydium_network_name[i],buff+RAYDIUM_NETWORK_PACKET_OFFSET+1);
...
A proof-of-concept for testing the first 3 bugs is available here:
http://aluigi.org/poc/raydiumx.zip
And here is a (interesting, I think) part of my response:
Code:
Hi,
First of all, thanks for the time you takes working on this project. Some of theses bugs are already known, but some others, not (good point for raydium_network_netcall_exec() for example !). There's also some potential buffer overflows in ode_net.c, as for example with raydium_ode_network_read(),which reads as many events as said in the first byte of the packet :
memcpy(&n,data+RAYDIUM_NETWORK_PACKET_OFFSET,sizeof(n));
if(type==RAYDIUM_NETWORK_PACKET_ODE_DATA)
for(i=0;i<n;i++)
{
get=(raydium_ode_network_Event *)(data+RAYDIUM_NETWORK_PACKET_OFFSET+sizeof(n)+(i*sizeof(*get)));
raydium_ode_network_apply(get);
}
There's probably a lot more errors like that, since the network API was built very naively (no htonl/ntohl, no security considerations, ...), and your work is a good start for us to correct all this.
Let's correct all this, now !