OpenVAS Scanner 23.40.3
nasl_builtin_openvas_tcp_scanner.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 2004 Michel Arboi <mikhail@nessus.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "../misc/network.h"
8#include "../misc/plugutils.h"
10#include "nasl_lex_ctxt.h"
11
12#include <errno.h> /* for errno() */
13#include <fcntl.h> /* for fcntl() */
14#include <glib.h>
15#include <gvm/base/logging.h>
16#include <gvm/base/prefs.h> /* for prefs_get */
17#include <netdb.h> /* for getprotobyname() */
18#include <stdio.h> /* for fprintf() */
19#include <stdlib.h> /* for atoi() */
20#include <string.h> /* for strcmp() */
21#include <sys/resource.h> /* for getrlimit() */
22#include <sys/socket.h> /* for socket() */
23#include <sys/time.h> /* for gettimeofday() */
24#include <sys/types.h> /* for socket() */
25#include <unistd.h> /* for close() */
26
27#ifdef LINUX
28#include <netinet/ip.h>
29#include <netinet/tcp.h>
30#endif
31#include <limits.h>
32#include <math.h> /* for sqrt(), floor() */
33
34#if !defined FD_SETSIZE || FD_SETSIZE > 1024
35#define GRAB_MAX_SOCK 1024
36#else
37#define GRAB_MAX_SOCK FD_SETSIZE
38#endif
39
40#if !defined FD_SETSIZE || FD_SETSIZE > 32
41#define GRAB_MIN_SOCK 32
42#else
43#define GRAB_MIN_SOCK FD_SETSIZE
44#warn "FD_SETSIZE is lower than 32"
45#endif
46
47#if !defined FD_SETSIZE || FD_SETSIZE > 128
48#define GRAB_MAX_SOCK_SAFE 128
49#else
50#define GRAB_MAX_SOCK_SAFE FD_SETSIZE
51#warn "FD_SETSIZE is lower than 128"
52#endif
53
54#define MAX_PASS_NB 16
55
56#ifndef MAXINT
57#define MAXINT 0x7fffffffL
58#endif
59
60#undef G_LOG_DOMAIN
64#define G_LOG_DOMAIN "lib nasl"
65
66typedef struct
67{
68 int fd;
69 struct timeval tictac; /* open time */
70 unsigned short port;
71 unsigned char state;
73
74#define DIFFTV(t1, t2) \
75 (t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)
76#define DIFFTVu(t1, t2) \
77 ((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))
78
79#define GRAB_SOCKET_UNUSED 0
80#define GRAB_SOCKET_OPENING 1
81#define GRAB_SOCKET_OPEN 2
82
83#define GRAB_PORT_UNKNOWN 0
84#define GRAB_PORT_CLOSED 1
85#define GRAB_PORT_OPEN 2
86#define GRAB_PORT_SILENT 3
87#define GRAB_PORT_REJECTED 4
88#define GRAB_PORT_NOT_TESTED 254
89#define GRAB_PORT_TESTING 255
90
91#define COMPUTE_RTT
92/*
93 * RTT is always estimated (at least, the maximum is remembered)
94 * If you want to enable the "statistics", define COMPUTE_RTT and link
95 * the plugin with libm (we need sqrt)
96 */
97/* Linux re-sends a SYN packet after 3 s
98 * anyway, I don't think that we can have a RTT bigger than 2 s
99 */
100#define MAX_SANE_RTT 2000000 /* micro-seconds */
101
102static int
104{
105#ifndef SO_LINGER
106 shutdown (s, 2);
107#endif
108 return close (s);
109}
110
111static int
112std_port (int port)
113{
114 (void) port;
115 return 0;
120}
121
122static int
123double_check_std_ports (unsigned char *ports_states)
124{
125 int port, tbd_nb = 0;
126
127 for (port = 1; port <= 65535; port++)
128 if (std_port (port) && ports_states[port] == GRAB_PORT_SILENT)
129 {
130 ports_states[port] = GRAB_PORT_UNKNOWN;
131 tbd_nb++;
132 }
133 else if (ports_states[port] == GRAB_PORT_UNKNOWN)
134 {
135 g_message ("openvas_tcp_scanner: bug in double_check_std_ports!"
136 " Unknown port %d status",
137 port);
138 tbd_nb++;
139 }
140 return tbd_nb;
141}
142
143static int
144banner_grab (const struct in6_addr *pia, const char *portrange,
145 const int read_timeout, int min_cnx, int max_cnx,
146 struct script_infos *desc)
147{
148 char buf[2048], kb[64];
149 int s, tcpproto, pass;
150 struct protoent *proto;
151 fd_set rfs, wfs, efs;
152 struct timeval timeout, ti;
153 struct sockaddr_in sa;
154 struct sockaddr_in6 sa6;
155 int len;
156 int retval;
157 int port = 23;
158 int imax, i, j, scanned_ports, x, opt;
159 unsigned int optsz;
160 int minport;
161 unsigned char ports_states[65536];
163 int open_sock_nb, open_sock_max, open_sock_max2;
164 int unfiltered_ports_nb, filtered_ports_nb;
165 int dropped_nb, timeout_nb, dropped_flag = 0;
166 int old_filtered = -1, old_opened = -1;
167 int open_ports_nb, closed_ports_nb;
168 int untested_ports_nb, total_ports_nb;
169 int cnx_max[3], rtt_max[3], rtt_min[3], ping_rtt = 0;
170#if defined COMPUTE_RTT
171 double rtt_sum[3], rtt_sum2[3];
172 int rtt_nb[3];
173 static const char *rtt_type[] = {"unfiltered", "open", "closed"};
174#endif
175 time_t start_time = time (NULL), start_time_1pass, end_time;
176 long diff_time, diff_time1;
177 int rst_rate_limit_flag = 0, doublecheck_flag = 0;
178#if defined COMPUTE_RTT
179 double mean, sd = -1.0, emax = -1.0;
180#endif
181
182 proto = getprotobyname ("tcp");
183 if (proto == NULL)
184 {
185 perror ("tcp");
186 return -1;
187 }
188 tcpproto = proto->p_proto;
189
190 for (i = 0; i < (int) (sizeof (ports_states) / sizeof (*ports_states)); i++)
191 ports_states[i] = GRAB_PORT_NOT_TESTED;
192 scanned_ports = 0;
193 for (i = 0; i < 3; i++)
194 {
195#if defined COMPUTE_RTT
196 rtt_sum[i] = rtt_sum2[i] = 0.0;
197 rtt_nb[i] = 0;
198#endif
199 rtt_max[i] = cnx_max[i] = 0;
200 rtt_min[i] = MAXINT;
201 }
202
203 {
204 char *k;
205 int type = 0;
206 k = plug_get_key (desc, "/tmp/ping/RTT", &type, NULL, 0);
207 if (type == ARG_STRING && k != NULL)
208 ping_rtt = atoi (k);
209 else if (type == ARG_INT)
210 ping_rtt = GPOINTER_TO_SIZE (k);
211 else if (type >= 0)
212 g_message ("openvas_tcp_scanner: unknown key type %d", type);
213 g_free (k);
214 if (ping_rtt < 0 || ping_rtt > MAX_SANE_RTT)
215 ping_rtt = 0;
216 }
217
218 {
219 char *p, *q;
220 int po1, po2 = 0;
221 p = (char *) portrange;
222 untested_ports_nb = 0;
223
224 if (p)
225 while (*p != '\0')
226 {
227 while (*p == ',')
228 p++;
229
230 /* Scanner accepts only T:1-3,6,U:103-333,770 due to getpts. */
231
232 if (*p == 'T' && p[1] && p[1] == ':')
233 /* Skip over the leading "T:". */
234 p += 2;
235 else if (*p == 'U' && p[1] && p[1] == ':')
236 /* "U:" for UDP. Skip the rest. */
237 break;
238
239 if (*p == '-')
240 {
241 po1 = 1;
242 q = p + 1;
243 po2 = strtol (q, &p, 10);
244 if (q == p)
245 {
246 g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
247 return -1;
248 }
249 }
250 else
251 {
252 po1 = strtol (p, &q, 10);
253 if (q == p)
254 {
255 g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
256 return -1;
257 }
258 if (*q == ',')
259 {
260 p = q + 1;
261 po2 = po1;
262 }
263 else if (*q == '\0')
264 {
265 p = q;
266 po2 = po1;
267 }
268 else if (*q == '-')
269 {
270 if (q[1] == '\0')
271 {
272 po2 = 65535;
273 p = q + 1;
274 }
275 else
276 {
277 po2 = strtol (q + 1, &p, 10);
278 if (q + 1 == p)
279 {
280 g_message ("openvas_tcp_scanner: Cannot parse '%s'",
281 p);
282 return -1;
283 }
284 }
285 }
286
287 if (po1 > 65535)
288 {
289 g_message ("%s: Wrong port '%d'. It will be skipped.", __func__, po1);
290 continue;
291 }
292 if (po2 > 65535)
293 {
294 g_message ("%s: Wrong port '%d'. It will be skipped.", __func__, po2);
295 continue;
296 }
297 }
298 for (i = po1; i <= po2; i++)
299 {
300 ports_states[i] = GRAB_PORT_UNKNOWN;
301 untested_ports_nb++;
302 }
303 }
304 else
305 {
306 g_message ("openvas_tcp_scanner: port list empty");
307 return -1;
308 }
309 }
310
311 for (i = 0; i < max_cnx; i++)
312 {
313 sockets[i].state = GRAB_SOCKET_UNUSED;
314 sockets[i].fd = -1;
315 }
316
317 open_sock_nb = 0;
318 open_sock_max = min_cnx;
319 open_sock_max2 = max_cnx;
320
321 open_ports_nb = closed_ports_nb = filtered_ports_nb = unfiltered_ports_nb = 0;
322
323 for (pass = 1; pass <= MAX_PASS_NB; pass++)
324 {
325 int open_ports_nb1 = 0, closed_ports_nb1 = 0;
326 int wait_sock_nb = 0;
327
328 minport = 1;
329 start_time_1pass = time (NULL);
330 FD_ZERO (&rfs);
331 FD_ZERO (&wfs);
332 imax = -1;
333
334 while (scanned_ports < 65535)
335 {
336 total_ports_nb =
337 unfiltered_ports_nb + filtered_ports_nb + untested_ports_nb;
338 while (open_sock_nb < open_sock_max)
339 {
340 for (port = minport;
341 port <= 65535 && ports_states[port] != GRAB_PORT_UNKNOWN;
342 port++)
343 ;
344 if (port > 65535)
345 break;
346 minport = port;
347
348 ports_states[port] = GRAB_PORT_TESTING;
349 if (IN6_IS_ADDR_V4MAPPED (pia))
350 {
351 s = socket (PF_INET, SOCK_STREAM, tcpproto);
352 }
353 else
354 {
355 s = socket (PF_INET6, SOCK_STREAM, tcpproto);
356 }
357 if (s < 0)
358 {
359 if (errno == ENFILE) /* File table overflow */
360 {
361 open_sock_max = open_sock_max2 = open_sock_nb / 2 - 1;
362 /* NB: if open_sock_max2 < 0, the scanner aborts */
363 /* DEBUG: otherwise, we print a less frigthtening message
364 */
365 continue;
366 }
367 else if (errno == EMFILE) /* Too many open files */
368 {
369 x = open_sock_nb / 16; /* 6.25% */
370 open_sock_max = open_sock_max2 =
371 open_sock_nb - (x > 0 ? x : 1);
372 /* NB: if open_sock_max2 < 0, the scanner aborts */
373 /* DEBUG: otherwise, we print a less frigthtening message
374 */
375 continue;
376 }
377 else
378 {
379 perror ("socket");
380 return -1;
381 }
382 }
383#if defined FD_SETSIZE
384 if (s >= FD_SETSIZE)
385 {
386 open_sock_max--;
387 open_sock_max2--;
388 if (close (s) < 0)
389 perror ("close");
390 continue;
391 }
392#endif
393
394 if ((x = fcntl (s, F_GETFL)) < 0)
395 {
396 perror ("fcntl(F_GETFL)");
397 close (s);
398 return -1;
399 }
400 if (fcntl (s, F_SETFL, x | O_NONBLOCK) < 0)
401 {
402 perror ("fcntl(F_SETFL)");
403 close (s);
404 return -1;
405 }
406
407#ifdef SO_LINGER
408 {
409 struct linger l;
410
411 l.l_onoff = 0;
412 l.l_linger = 0;
413 if (setsockopt (s, SOL_SOCKET, SO_LINGER, &l, sizeof (l)) < 0)
414 perror ("setsockopt(SO_LINGER)");
415 }
416#endif
417#if defined LINUX && defined IPTOS_RELIABILITY
418 /*
419 * IP TOS (RFC791) is obsoleted by RFC2474
420 * RFC3168 deprecates IPTOS_MINCOST, as it conflicts with
421 * the "ECN capable" flags
422 */
423 x = IPTOS_RELIABILITY;
424 if (setsockopt (s, SOL_IP, IP_TOS, &x, sizeof (x)) < 0)
425 perror ("setsockopt(IP_TOS");
426#endif
427 bzero (&sa, sizeof (sa));
428 bzero (&sa6, sizeof (sa6));
429 if (IN6_IS_ADDR_V4MAPPED (pia))
430 {
431 sa.sin_addr.s_addr = pia->s6_addr32[3];
432 sa.sin_family = AF_INET;
433 sa.sin_port = htons (port);
434 len = sizeof (struct sockaddr_in);
435 retval = connect (s, (struct sockaddr *) &sa, len);
436 }
437 else
438 {
439 memcpy (&sa6.sin6_addr, pia, sizeof (struct in6_addr));
440 sa6.sin6_family = AF_INET6;
441 sa6.sin6_port = htons (port);
442 len = sizeof (struct sockaddr_in6);
443 retval = connect (s, (struct sockaddr *) &sa6, len);
444 }
445 if (retval < 0)
446 {
447 switch (errno)
448 {
449 case EINPROGRESS:
450 case EALREADY:
451 sockets[open_sock_nb].fd = s;
452 sockets[open_sock_nb].port = port;
453 sockets[open_sock_nb].state = GRAB_SOCKET_OPENING;
454 (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
455 open_sock_nb++;
456 FD_SET (s, &wfs);
457 if (s > imax)
458 imax = s;
459 break;
460
461 case EAGAIN:
462 x = open_sock_nb / 16; /* 6.25% */
463 open_sock_max = open_sock_max2 =
464 open_sock_nb - (x > 0 ? x : 1);
465 /* If open_sock_max2 < 0, the scanner aborts */
466 continue;
467
468 case ECONNREFUSED:
469 ports_states[port] = GRAB_PORT_CLOSED;
470 my_socket_close (s);
471 unfiltered_ports_nb++;
472 closed_ports_nb++;
473 closed_ports_nb1++;
474 untested_ports_nb--;
475 continue;
476
477 case ENETUNREACH:
478 case EHOSTUNREACH:
479 ports_states[port] = GRAB_PORT_REJECTED;
480 my_socket_close (s);
481 filtered_ports_nb++;
482 untested_ports_nb--;
483 continue;
484
485 default:
486 perror ("connect");
487 return -1;
488 }
489 }
490 else /* This should not happen! */
491 {
492 sockets[open_sock_nb].fd = s;
493 sockets[open_sock_nb].port = port;
494 sockets[open_sock_nb].state = GRAB_SOCKET_OPEN;
495 (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
496 open_sock_nb++;
497 ports_states[port] = GRAB_PORT_OPEN;
498 unfiltered_ports_nb++;
499 open_ports_nb++;
500 open_ports_nb1++;
501 wait_sock_nb++;
502 untested_ports_nb--;
503 scanner_add_port (desc, port, "tcp");
504 }
505 if (imax >= 0)
506 {
507 timeout.tv_sec = timeout.tv_usec = 0;
508 if (select (imax + 1, NULL, &wfs, NULL, &timeout) > 0)
509 break;
510 }
511 }
512
513 if (open_sock_max2 <= 0) /* file table is full */
514 return -1;
515
516 if (open_sock_nb == 0)
517 goto end;
518
519 FD_ZERO (&rfs);
520 FD_ZERO (&wfs);
521 FD_ZERO (&efs);
522 imax = -1;
523
524 for (i = 0; i < open_sock_nb; i++)
525 {
526 if (sockets[i].fd >= 0)
527 {
528 switch (sockets[i].state)
529 {
530 case GRAB_SOCKET_OPEN:
531 FD_SET (sockets[i].fd, &rfs);
532 break;
534 FD_SET (sockets[i].fd, &wfs);
535 break;
536 default:
537 break;
538 }
539 if (sockets[i].fd > imax)
540 imax = sockets[i].fd;
541 }
542 }
543
544 if (imax < 0)
545 {
546 if (untested_ports_nb > 0)
547 return -1;
548 else
549 goto end;
550 }
551
552 timeout_nb = 0;
553 dropped_nb = 0;
554 dropped_flag = 0;
555#if defined COMPUTE_RTT
556 if (rtt_nb[0] > 1)
557 {
558 /* All values are in micro-seconds */
559 int em, moy;
560
561 mean = rtt_sum[0] / (double) rtt_nb[0];
562 if ((double) rtt_max[0] > mean)
563 {
564 sd = sqrt ((rtt_sum2[0] / rtt_nb[0] - mean * mean)
565 * (double) rtt_nb[0] / (rtt_nb[0] - 1));
566 emax = mean + 3 * sd;
567 em = floor (emax + 0.5);
568 moy = floor (rtt_sum[0] / rtt_nb[0] + 0.5);
569 if (em <= moy)
570 em = moy;
571 if (rtt_max[0] > em)
572 rtt_max[0] = em;
573 }
574 if (rtt_max[0] < rtt_min[0])
575 rtt_max[0] = rtt_min[0];
576 }
577#endif
578 /*
579 * Some randomness is added to the timeout so that not all
580 * scanners fire at the same time when several firewalled
581 * machines are scanned in parallel.
582 */
583 if (wait_sock_nb == 0)
584 if (rtt_max[0] > 0 || ping_rtt > 0)
585 {
586 if (rtt_max[0] > 0)
587 x = rtt_max[0];
588 else
589 x = ping_rtt;
590
591 if (doublecheck_flag)
592 {
593 x = 3 * x + 20000;
594 if (x > MAX_SANE_RTT)
595 x = MAX_SANE_RTT;
596 }
597 if (x > 1000000) /* more that 1 s */
598 x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 100000;
599 else if (x > 20000) /* between 20 ms and 1 s */
600 x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 50000;
601 else /* less than 20 ms */
602 x = 20000 + (unsigned) (lrand48 () & 0x7FFFFFFF) % 20000;
603 timeout.tv_sec = x / 1000000;
604 timeout.tv_usec = x % 1000000;
605 }
606 else
607 {
608 /* Max RTT = 2 s ? */
609 timeout.tv_sec = 2;
610 timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 250000;
611 }
612 else
613 {
614 timeout.tv_sec = read_timeout; /* * 2 ? */
615 timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 500000;
616 }
617 i = 0;
618 do
619 x = select (imax + 1, &rfs, &wfs, NULL, &timeout);
620 while (i++ < 10 && x < 0 && errno == EINTR);
621
622 if (x < 0)
623 {
624 perror ("select");
625 return -1;
626 }
627 else if (x == 0) /* timeout */
628 {
629 for (i = 0; i < open_sock_nb; i++)
630 {
631 if (sockets[i].fd > 0)
632 {
633 my_socket_close (sockets[i].fd);
634 sockets[i].fd = -1;
635 switch (sockets[i].state)
636 {
638 ports_states[sockets[i].port] = GRAB_PORT_SILENT;
639 filtered_ports_nb++;
640 dropped_nb++;
641 untested_ports_nb--;
642 break;
643 case GRAB_SOCKET_OPEN:
644 wait_sock_nb--;
645 break;
646 }
647 }
648 sockets[i].state = GRAB_SOCKET_UNUSED;
649 }
650 }
651 else /* something to do */
652 {
653 (void) gettimeofday (&ti, NULL);
654 for (i = 0; i < open_sock_nb; i++)
655 {
656 if (sockets[i].fd > 0)
657 {
658 if (FD_ISSET (sockets[i].fd, &wfs))
659 {
660 opt = 0;
661 optsz = sizeof (opt);
662 if (getsockopt (sockets[i].fd, SOL_SOCKET, SO_ERROR,
663 &opt, &optsz)
664 < 0)
665 {
666 perror ("getsockopt");
667 return -1;
668 }
669
670 x = DIFFTVu (ti, sockets[i].tictac);
671 if (opt != 0)
672 {
673 errno = opt;
674 if (x > cnx_max[2])
675 cnx_max[2] = x;
676 if (x < rtt_min[2])
677 rtt_min[2] = x;
678 if (x < MAX_SANE_RTT)
679 {
680 if (x > rtt_max[2])
681 rtt_max[2] = x;
682#if defined COMPUTE_RTT
683 rtt_nb[2]++;
684 rtt_sum[2] += (double) x;
685 rtt_sum2[2] += (double) x * (double) x;
686#endif
687 }
688
689 my_socket_close (sockets[i].fd);
690 sockets[i].fd = -1;
691 sockets[i].state = GRAB_SOCKET_UNUSED;
692
693 untested_ports_nb--;
694 switch (opt)
695 {
696 case ENETUNREACH:
697 case EHOSTUNREACH:
698 ports_states[sockets[i].port] =
700 filtered_ports_nb++;
701 break;
702
703 case ECONNREFUSED:
704 default:
705 ports_states[sockets[i].port] =
707 unfiltered_ports_nb++;
708 closed_ports_nb++;
709 closed_ports_nb1++;
710 break;
711 }
712 }
713 else
714 {
715 sockets[i].state = GRAB_SOCKET_OPEN;
716 if (x > cnx_max[1])
717 cnx_max[1] = x;
718 if (x < rtt_min[1])
719 rtt_min[1] = x;
720 if (x < MAX_SANE_RTT)
721 {
722 if (x > rtt_max[1])
723 rtt_max[1] = x;
724#if defined COMPUTE_RTT
725 rtt_nb[1]++;
726 rtt_sum[1] += (double) x;
727 rtt_sum2[1] += (double) x * (double) x;
728#endif
729 }
730
731 unfiltered_ports_nb++;
732 open_ports_nb++;
733 open_ports_nb1++;
734 untested_ports_nb--;
735 ports_states[sockets[i].port] = GRAB_PORT_OPEN;
736 scanner_add_port (desc, sockets[i].port, "tcp");
737 wait_sock_nb++;
738 snprintf (kb, sizeof (kb),
739 "TCPScanner/CnxTime1000/%u",
740 sockets[i].port);
741 plug_set_key (desc, kb, ARG_INT,
742 GSIZE_TO_POINTER (x / 1000));
743 snprintf (kb, sizeof (kb),
744 "TCPScanner/CnxTime/%u",
745 sockets[i].port);
747 desc, kb, ARG_INT,
748 GSIZE_TO_POINTER ((x + 500000) / 1000000));
749 sockets[i].tictac = ti;
750 }
751 if (x > cnx_max[0])
752 cnx_max[0] = x;
753 if (x < rtt_min[0])
754 rtt_min[0] = x;
755 if (x < MAX_SANE_RTT)
756 {
757 if (x > rtt_max[0])
758 rtt_max[0] = x;
759#if defined COMPUTE_RTT
760 rtt_nb[0]++;
761 rtt_sum[0] += (double) x;
762 rtt_sum2[0] += (double) x * (double) x;
763#endif
764 }
765 }
766 else if (FD_ISSET (sockets[i].fd, &rfs))
767 {
768 x = read (sockets[i].fd, buf, sizeof (buf) - 1);
769 if (x > 0)
770 {
771 char buf2[sizeof (buf) * 2 + 1];
772 int y, flag = 0;
773
774 for (y = 0; y < x; y++)
775 {
776 sprintf (buf2 + 2 * y, "%02x",
777 (unsigned char) buf[y]);
778 if (buf[y] == '\0')
779 flag = 1;
780 }
781 buf2[2 * x - 1] = '\0';
782 if (flag)
783 {
784 snprintf (kb, sizeof (kb), "BannerHex/%u",
785 sockets[i].port);
786 plug_set_key (desc, kb, ARG_STRING, buf2);
787 }
788
789 buf[x] = '\0';
790 snprintf (kb, sizeof (kb), "Banner/%u",
791 sockets[i].port);
792 plug_set_key (desc, kb, ARG_STRING, buf);
793 x = DIFFTVu (ti, sockets[i].tictac) / 1000;
794 snprintf (kb, sizeof (kb),
795 "TCPScanner/RwTime1000/%u",
796 sockets[i].port);
797 plug_set_key (desc, kb, ARG_INT,
798 GSIZE_TO_POINTER (x));
799 snprintf (kb, sizeof (kb), "TCPScanner/RwTime/%u",
800 sockets[i].port);
802 desc, kb, ARG_INT,
803 GSIZE_TO_POINTER ((x + 500) / 1000));
804 }
805 wait_sock_nb--;
806 my_socket_close (sockets[i].fd);
807 sockets[i].fd = -1;
808 sockets[i].state = GRAB_SOCKET_UNUSED;
809 }
810 }
811 }
812 }
813
814 (void) gettimeofday (&ti, NULL);
815 for (i = 0; i < open_sock_nb; i++)
816 if (sockets[i].fd >= 0
817 && DIFFTV (ti, sockets[i].tictac) >= read_timeout)
818 {
819 switch (sockets[i].state)
820 {
821 case GRAB_SOCKET_OPEN:
822 timeout_nb++;
823 wait_sock_nb--;
824 snprintf (kb, sizeof (kb), "/tmp/NoBanner/%u",
825 sockets[i].port);
826 plug_set_key (desc, kb, ARG_INT, (void *) 1);
827 break;
829 ports_states[sockets[i].port] = GRAB_PORT_SILENT;
830 filtered_ports_nb++;
831 dropped_nb++;
832 untested_ports_nb--;
833 break;
834 default:
835 g_message (
836 "openvas_tcp_scanner: Unhandled case %d at %s:%d",
837 sockets[i].state, __FILE__, __LINE__);
838 break;
839 }
840 my_socket_close (sockets[i].fd);
841 sockets[i].fd = -1;
842 sockets[i].state = GRAB_SOCKET_UNUSED;
843 }
844
845 if (dropped_nb > 0 && dropped_nb >= (open_sock_nb * 3) / 4
846 && (dropped_nb < filtered_ports_nb
847 || dropped_nb > unfiltered_ports_nb))
848 {
849 /* firewalled machine? */
850 open_sock_max += dropped_nb;
851 if (open_sock_max2 < max_cnx)
852 open_sock_max2++;
853 }
854 else if (dropped_nb > 0)
855 {
856 dropped_flag = 1;
857 open_sock_max -= (dropped_nb + 2) / 3;
858 if (open_sock_max < min_cnx)
859 open_sock_max = min_cnx;
860 open_sock_max2 = (open_sock_max + 3 * open_sock_max2) / 4;
861 }
862 else if (dropped_nb == 0 && dropped_flag)
863 {
864 /* re-increase number of open sockets */
865 open_sock_max++;
866 }
867 open_sock_max += timeout_nb;
868 if (open_sock_max > open_sock_max2)
869 {
870 open_sock_max = open_sock_max2;
871 }
872 if (open_sock_max < min_cnx)
873 open_sock_max = min_cnx;
874 for (i = 0; i < open_sock_nb;)
875 if (sockets[i].state == GRAB_SOCKET_UNUSED || sockets[i].fd < 0)
876 {
877 for (j = i + 1; j < open_sock_nb
878 && (sockets[j].state == GRAB_SOCKET_UNUSED
879 || sockets[j].fd < 0);
880 j++)
881 ;
882 if (j < open_sock_nb)
883 memmove (sockets + i, sockets + j,
884 sizeof (*sockets) * (max_cnx - j));
885 open_sock_nb -= j - i;
886 }
887 else
888 i++;
889 }
890
891 end:
892 end_time = time (NULL);
893 diff_time1 = end_time - start_time_1pass;
894 diff_time = end_time - start_time;
895 if (dropped_flag
896 || (pass == 1 && filtered_ports_nb > 10 && closed_ports_nb > 10)
897 || (pass > 1 && filtered_ports_nb > 0))
898 {
899 if (doublecheck_flag && rst_rate_limit_flag
900 && open_ports_nb == old_opened)
901 break;
902 old_opened = open_ports_nb;
903
904 doublecheck_flag = 0;
905 if (filtered_ports_nb == old_filtered)
906 break;
907
908 if (pass > 1 && open_ports_nb1 == 0 && closed_ports_nb1 >= min_cnx &&
909 /*
910 * Default value is 100 RST per second on OpenBSD,
911 * 200 on FreeBSD and 40 on Solaris
912 */
913 /* 1st check on this pass only */
914 closed_ports_nb1 >= (diff_time1 + 1) * 10
915 && closed_ports_nb1 < (diff_time1 + 1) * 201 &&
916 /* 2nd check on all passes */
917 closed_ports_nb >= (diff_time + 1) * 10
918 && closed_ports_nb < (diff_time + 1) * 201)
919 {
920 /* BSD-like system */
921 int break_flag =
922 (open_sock_max2 <= GRAB_MAX_SOCK_SAFE) || rst_rate_limit_flag;
923 int tbd = break_flag && !doublecheck_flag
924 ? double_check_std_ports (ports_states)
925 : 0;
926 if (tbd > 0)
927 {
928 doublecheck_flag = 1;
929 break_flag = 0;
930 }
931 rst_rate_limit_flag++;
932 if (break_flag)
933 break;
934 }
935 /*
936 * With doublecheck_flag, the range of tested port is different, so
937 * we'd better count the number of filtered ports
938 */
939 old_filtered = 0;
940 for (port = 1; port <= 65535; port++)
941 if (ports_states[port] == GRAB_PORT_SILENT)
942 {
943 ports_states[port] = GRAB_PORT_UNKNOWN;
944 old_filtered++;
945 }
946 untested_ports_nb = old_filtered;
947 filtered_ports_nb = 0;
948 open_sock_max = min_cnx / (pass + 1);
949 if (open_sock_max < 1)
950 open_sock_max = 1;
951 if (!dropped_flag)
952 {
953 open_sock_max2 *= 2;
954 open_sock_max2 /= 3;
955 }
956 else if (rst_rate_limit_flag)
957 {
958 if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
959 open_sock_max2 = GRAB_MAX_SOCK_SAFE;
960 if (open_sock_max > GRAB_MAX_SOCK_SAFE)
961 open_sock_max = GRAB_MAX_SOCK_SAFE;
962 }
963 else if (open_sock_max2 <= open_sock_max)
964 open_sock_max2 = open_sock_max * 2;
965 }
966 else if (filtered_ports_nb > 0)
967 {
968 int tbd_nb = 0;
969 doublecheck_flag = 1;
970 /* Double check standard ports, just to avoid being ridiculous */
971
972 if ((tbd_nb = double_check_std_ports (ports_states)) == 0)
973 break;
974 old_filtered = untested_ports_nb = tbd_nb;
975 filtered_ports_nb = 0;
976 open_sock_max = min_cnx / pass;
977 if (open_sock_max2 <= open_sock_max)
978 open_sock_max2 = open_sock_max * 2;
979 if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
980 open_sock_max2 = GRAB_MAX_SOCK_SAFE;
981 if (open_sock_max > GRAB_MAX_SOCK_SAFE)
982 open_sock_max = GRAB_MAX_SOCK_SAFE;
983 }
984 else
985 break;
986 } /* for pass = ... */
987
988 if (pass > MAX_PASS_NB)
989 {
990 pass--;
991 filtered_ports_nb = old_filtered;
992 }
993
994 plug_set_key (desc, "TCPScanner/NbPasses", ARG_INT, GSIZE_TO_POINTER (pass));
995
996#if defined COMPUTE_RTT
997 for (i = 0; i < 3; i++)
998 if (rtt_nb[i] > 0)
999 {
1000 char rep[64];
1001 double crtt_mean, crtt_sd = -1.0, crtt_emax = -1.0;
1002
1003 /* Convert from micro-seconds to seconds */
1004 rtt_sum[i] /= 1e6;
1005 rtt_sum2[i] /= 1e12;
1006
1007 crtt_mean = rtt_sum[i] / rtt_nb[i];
1008 snprintf (rep, sizeof (rep), "%6g", crtt_mean);
1009 snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT", rtt_type[i]);
1010 plug_set_key (desc, kb, ARG_STRING, rep);
1011 x = floor (crtt_mean * 1000 + 0.5);
1012 snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT1000", rtt_type[i]);
1013 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1014 /* rtt_max is integer (uS) */
1015 snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT1000", rtt_type[i]);
1016 plug_set_key (desc, kb, ARG_INT,
1017 GSIZE_TO_POINTER ((rtt_max[i] + 500) / 1000));
1018 snprintf (rep, sizeof (rep), "%6g",
1019 (rtt_max[i] + 500000.0) / 1000000.0);
1020 snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT", rtt_type[i]);
1021 plug_set_key (desc, kb, ARG_STRING, rep);
1022 if (rtt_nb[i] > 1)
1023 {
1024 crtt_sd = sqrt ((rtt_sum2[i] / rtt_nb[i] - crtt_mean * crtt_mean)
1025 * rtt_nb[i] / (rtt_nb[i] - 1));
1026 crtt_emax = crtt_mean + 3 * crtt_sd;
1027 snprintf (rep, sizeof (rep), "%6g", crtt_sd);
1028 snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT", rtt_type[i]);
1029 plug_set_key (desc, kb, ARG_STRING, rep);
1030 x = floor (crtt_sd * 1000 + 0.5);
1031 snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT1000", rtt_type[i]);
1032 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1033 snprintf (rep, sizeof (rep), "%6g", crtt_emax);
1034 snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT",
1035 rtt_type[i]);
1036 plug_set_key (desc, kb, ARG_STRING, rep);
1037 x = floor (crtt_emax * 1000 + 0.5);
1038 snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT1000",
1039 rtt_type[i]);
1040 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1041 }
1042 }
1043#endif
1044 plug_set_key (desc, "TCPScanner/OpenPortsNb", ARG_INT,
1045 GSIZE_TO_POINTER (open_ports_nb));
1046 plug_set_key (desc, "TCPScanner/ClosedPortsNb", ARG_INT,
1047 GSIZE_TO_POINTER (closed_ports_nb));
1048 plug_set_key (desc, "TCPScanner/FilteredPortsNb", ARG_INT,
1049 GSIZE_TO_POINTER (filtered_ports_nb));
1050 plug_set_key (desc, "TCPScanner/RSTRateLimit", ARG_INT,
1051 GSIZE_TO_POINTER (rst_rate_limit_flag));
1052 if (untested_ports_nb <= 0)
1053 plug_set_key (desc, "Host/full_scan", ARG_INT, GSIZE_TO_POINTER (1));
1054 plug_set_key (desc, "Host/num_ports_scanned", ARG_INT,
1055 GSIZE_TO_POINTER ((total_ports_nb - untested_ports_nb)));
1056 return 0;
1057}
1058
1059tree_cell *
1061{
1062 struct script_infos *desc = lexic->script_infos;
1063 const char *port_range = prefs_get ("port_range");
1064 const char *p;
1065 struct in6_addr *p_addr;
1066 unsigned int timeout = 0, max_cnx, min_cnx, x;
1067 int safe_checks = prefs_get_bool ("safe_checks");
1068
1069 p = prefs_get ("checks_read_timeout");
1070 if (p != NULL)
1071 timeout = atoi (p);
1072 if (timeout <= 0)
1073 timeout = 5;
1074 {
1075 int max_host = 0, max_checks = 0, cur_sys_fd = 0, max_sys_fd = 0;
1076 struct rlimit rlim;
1077 FILE *fp;
1078 int i;
1079 double loadavg[3], maxloadavg = -1.0;
1080 int stderr_fd = dup (2);
1081 int devnull_fd = open ("/dev/null", O_WRONLY);
1082 /* Avoid error messages from sysctl */
1083 if (devnull_fd <= 0)
1084 {
1085 if (stderr_fd != -1)
1086 close (stderr_fd);
1087 return NULL;
1088 }
1089 dup2 (devnull_fd, 2);
1090
1091 p = prefs_get ("max_hosts");
1092 if (p != NULL)
1093 max_host = atoi (p);
1094 if (max_host <= 0)
1095 max_host = 15;
1096
1097 p = prefs_get ("max_checks");
1098 if (p != NULL)
1099 max_checks = atoi (p);
1100 if (max_checks <= 0 || max_checks > 5)
1101 {
1102 max_checks = 5; /* bigger values do not make sense */
1103 g_debug ("openvas_tcp_scanner: max_checks forced to %d", max_checks);
1104 }
1105
1106 min_cnx = 8 * max_checks;
1107 if (safe_checks)
1108 max_cnx = 24 * max_checks;
1109 else
1110 max_cnx = 80 * max_checks;
1111
1112 getloadavg (loadavg, 3);
1113 for (i = 0; i < 3; i++)
1114 if (loadavg[i] > maxloadavg)
1115 maxloadavg = loadavg[i];
1116
1117 if (max_sys_fd <= 0)
1118 {
1119 fp = popen ("sysctl fs.file-nr", "r");
1120 if (fp != NULL)
1121 {
1122 if (fscanf (fp, "%*s = %*d %d %d", &cur_sys_fd, &max_sys_fd) == 1)
1123 max_sys_fd -= cur_sys_fd;
1124 else
1125 max_sys_fd = 0;
1126 pclose (fp);
1127 }
1128 }
1129 if (max_sys_fd <= 0)
1130 {
1131 fp = popen ("sysctl fs.file-max", "r");
1132 if (fp != NULL)
1133 {
1134 if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1135 max_sys_fd = 0;
1136 pclose (fp);
1137 }
1138 }
1139
1140 if (max_sys_fd <= 0)
1141 {
1142 fp = popen ("sysctl kern.maxfiles", "r");
1143 if (fp != NULL)
1144 {
1145 if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1146 max_sys_fd = 0;
1147 pclose (fp);
1148 }
1149 }
1150
1151 /* Restore stderr */
1152 close (devnull_fd);
1153 dup2 (stderr_fd, 2);
1154 close (stderr_fd);
1155
1156 if (maxloadavg >= 0.0)
1157 max_cnx /= (1.0 + maxloadavg);
1158
1159 if (max_sys_fd <= 0)
1160 max_sys_fd = 16384; /* reasonable default */
1161 /* Let's leave at least 1024 FD for other processes */
1162 if (max_sys_fd < 1024)
1163 x = GRAB_MIN_SOCK;
1164 else
1165 {
1166 max_sys_fd -= 1024;
1167 x = max_sys_fd / max_host;
1168 }
1169 if (max_cnx > x)
1170 max_cnx = x;
1171 if (max_cnx > GRAB_MAX_SOCK)
1172 max_cnx = GRAB_MAX_SOCK;
1173 if (max_cnx < GRAB_MIN_SOCK)
1174 max_cnx = GRAB_MIN_SOCK;
1175
1176 if (safe_checks && max_cnx > GRAB_MAX_SOCK_SAFE)
1177 max_cnx = GRAB_MAX_SOCK_SAFE;
1178
1179 if (getrlimit (RLIMIT_NOFILE, &rlim) < 0)
1180 perror ("getrlimit(RLIMIT_NOFILE)");
1181 else
1182 {
1183 /* value = one greater than the maximum file descriptor number */
1184 if (rlim.rlim_cur != RLIM_INFINITY && max_cnx >= rlim.rlim_cur)
1185 max_cnx = rlim.rlim_cur - 1;
1186 }
1187 x = max_cnx / 2;
1188 if (min_cnx > x)
1189 min_cnx = x > 0 ? x : 1;
1190 }
1191
1192 p_addr = desc->ip;
1193 if (p_addr == NULL)
1194 return NULL; // TODO: before it returned "1";
1195 if (banner_grab (p_addr, port_range, timeout, min_cnx, max_cnx, desc) < 0)
1196 return NULL; // TODO: before it returned "1";
1197 plug_set_key (desc, "Host/scanned", ARG_INT, (void *) 1);
1198 plug_set_key (desc, "Host/scanners/openvas_tcp_scanner", ARG_INT, (void *) 1);
1199 return NULL;
1200}
#define DIFFTV(t1, t2)
#define GRAB_PORT_TESTING
#define DIFFTVu(t1, t2)
#define GRAB_PORT_UNKNOWN
tree_cell * plugin_run_openvas_tcp_scanner(lex_ctxt *lexic)
#define GRAB_MAX_SOCK_SAFE
static int std_port(int port)
#define GRAB_PORT_REJECTED
#define GRAB_SOCKET_OPENING
static int my_socket_close(int s)
static int double_check_std_ports(unsigned char *ports_states)
#define GRAB_SOCKET_UNUSED
#define GRAB_PORT_NOT_TESTED
static int banner_grab(const struct in6_addr *pia, const char *portrange, const int read_timeout, int min_cnx, int max_cnx, struct script_infos *desc)
Header file for built-in plugins.
static struct timeval timeval(unsigned long val)
struct struct_lex_ctxt lex_ctxt
uint8_t len
tree_cell * safe_checks(lex_ctxt *lexic)
struct TC tree_cell
Header file for module network.
void scanner_add_port(struct script_infos *args, int port, char *proto)
Definition plugutils.c:1151
void plug_set_key(struct script_infos *args, char *name, int type, const void *value)
Definition plugutils.c:1060
void * plug_get_key(struct script_infos *args, char *name, int *type, size_t *len, int single)
Get values from a kb under the given key name.
Definition plugutils.c:1231
Header file for module plugutils.
#define ARG_STRING
Definition plugutils.h:19
#define ARG_INT
Definition plugutils.h:20
struct in6_addr * ip
Definition scanneraux.h:37
struct script_infos * script_infos