OpenVAS Scanner  22.7.9
nasl.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2023 Greenbone AG
2  * SPDX-FileCopyrightText: 2002-2005 Tenable Network Security
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
12 #include "nasl.h"
13 
14 #include "../misc/kb_cache.h" // for get_main_kb
15 #include "../misc/network.h"
16 #include "../misc/nvt_categories.h"
17 #include "../misc/plugutils.h"
18 #include "../misc/vendorversion.h"
19 #include "exec.h"
20 #include "nasl_lex_ctxt.h"
21 
22 #include <errno.h> /* for errno */
23 #include <gcrypt.h> /* for gcry_control */
24 #include <glib.h>
25 #include <gnutls/gnutls.h> /* for gnutls_check_version */
26 #include <gpgme.h> /* for gpgme_check_version */
27 #include <gvm/base/hosts.h> /* for gvm_hosts_* and gvm_host_* */
28 #include <gvm/base/networking.h> /* for gvm_source_iface_init */
29 #include <gvm/base/nvti.h>
30 #include <gvm/base/prefs.h> /* for prefs_get */
31 #include <gvm/util/kb.h> /* for kb_new */
32 #include <libssh/libssh.h> /* for ssh_version */
33 #include <signal.h> /* for SIGINT */
34 #include <stdlib.h> /* for exit */
35 #include <string.h> /* for strlen */
36 #include <sys/wait.h>
37 #include <unistd.h> /* for geteuid */
38 
39 #ifndef MAP_FAILED
40 #define MAP_FAILED ((void *) -1)
41 #endif
42 
43 #undef G_LOG_DOMAIN
44 
47 #define G_LOG_DOMAIN "lib nasl"
48 
49 extern char *
50 nasl_version (void);
51 
52 static void
53 my_gnutls_log_func (int level, const char *text)
54 {
55  fprintf (stderr, "[%d] (%d) %s", getpid (), level, text);
56  if (*text && text[strlen (text) - 1] != '\n')
57  putc ('\n', stderr);
58 }
59 
60 static struct script_infos *
61 init (struct in6_addr *ip, GSList *vhosts, kb_t kb)
62 {
63  struct script_infos *infos = g_malloc0 (sizeof (struct script_infos));
64 
65  infos->standalone = 1;
66  infos->key = kb;
67  infos->ip = ip;
68  infos->vhosts = vhosts;
69  if (prefs_get_bool ("test_empty_vhost"))
70  {
71  gvm_vhost_t *vhost =
72  gvm_vhost_new (addr6_as_str (ip), g_strdup ("IP-address"));
73  infos->vhosts = g_slist_prepend (infos->vhosts, vhost);
74  }
75  infos->globals = g_malloc0 (sizeof (struct scan_globals));
76 
77  return infos;
78 }
79 
80 extern FILE *nasl_trace_fp;
81 
82 static nvti_t *
84 {
85  nvti_t *nvti;
87 
88  nvti = nvti_new ();
89  infos->nvti = nvti;
90  if (exec_nasl_script (infos, mode) < 0)
91  {
92  printf ("%s could not be loaded\n", infos->name);
93  return NULL;
94  }
95  infos->nvti = NULL;
96  infos->oid = g_strdup (nvti_oid (nvti));
97 
98  return nvti;
99 }
100 
108 static int
109 nvti_category_is_safe (int category)
110 {
111  if (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST
112  || category == ACT_FLOOD || category == ACT_DENIAL)
113  return 0;
114  return 1;
115 }
116 
120 static void
122 {
123  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
124  return;
125  gcry_check_version (NULL);
126  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
127  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
128  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
129  gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
130 }
131 
137 int
138 main (int argc, char **argv)
139 {
140  struct script_infos *script_infos;
141  gvm_hosts_t *hosts;
142  gvm_host_t *host;
143  static gchar *target = NULL;
144  gchar *default_target = "127.0.0.1";
145  int mode = 0, err = 0, pos;
146  extern int global_nasl_debug;
147  GSList *unresolved;
148 
149  static gboolean display_version = FALSE;
150  static gboolean nasl_debug = FALSE;
151  static gboolean description_only = FALSE;
152  static gboolean both_modes = FALSE;
153  static gboolean parse_only = FALSE;
154  static gboolean do_lint = FALSE;
155  static gchar *trace_file = NULL;
156  static gchar *config_file = NULL;
157  static gchar *source_iface = NULL;
158  static gchar *port_range = NULL;
159  static gboolean with_safe_checks = FALSE;
160  static gboolean signing_mode = FALSE;
161  static gchar *include_dir = NULL;
162  static gchar **nasl_filenames = NULL;
163  static gchar **kb_values = NULL;
164  static int debug_tls = 0;
165  GError *error = NULL;
166  GOptionContext *option_context;
167  static GOptionEntry entries[] = {
168  {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
169  "Display version information", NULL},
170  {"debug", 'd', 0, G_OPTION_ARG_NONE, &nasl_debug,
171  "Output debug information to stderr.", NULL},
172  {"description", 'D', 0, G_OPTION_ARG_NONE, &description_only,
173  "Only run the 'description' part of the script", NULL},
174  {"both", 'B', 0, G_OPTION_ARG_NONE, &both_modes,
175  "Run in description mode before running the script.", NULL},
176  {"parse", 'p', 0, G_OPTION_ARG_NONE, &parse_only,
177  "Only parse the script, don't execute it", NULL},
178  {"lint", 'L', 0, G_OPTION_ARG_NONE, &do_lint,
179  "'lint' the script (extended checks)", NULL},
180  {"target", 't', 0, G_OPTION_ARG_STRING, &target,
181  "Execute the scripts against <target>", "<target>"},
182  {"trace", 'T', 0, G_OPTION_ARG_FILENAME, &trace_file,
183  "Log actions to <file> (or '-' for stderr)", "<file>"},
184  {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
185  "Configuration file", "<filename>"},
186  {"source-iface", 'e', 0, G_OPTION_ARG_STRING, &source_iface,
187  "Source network interface for established connections.", "<iface_name>"},
188  {"safe", 's', 0, G_OPTION_ARG_NONE, &with_safe_checks,
189  "Specifies that the script should be run with 'safe checks' enabled",
190  NULL},
191  {"disable-signing", 'X', 0, G_OPTION_ARG_NONE, &signing_mode,
192  "Run the script with disabled signature verification", NULL},
193  {"include-dir", 'i', 0, G_OPTION_ARG_STRING, &include_dir,
194  "Search for includes in <dir>", "<dir>"},
195  {"debug-tls", 0, 0, G_OPTION_ARG_INT, &debug_tls,
196  "Enable TLS debugging at <level>", "<level>"},
197  {"kb", 'k', 0, G_OPTION_ARG_STRING_ARRAY, &kb_values,
198  "Set KB key to value. Can be used multiple times", "<key=value>"},
199  {"port-range", 'r', 0, G_OPTION_ARG_STRING, &port_range,
200  "Set the <port-range> used by nasl scripts. ", "<port-range>"},
201  {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &nasl_filenames,
202  "Absolute path to one or more nasl scripts", "NASL_FILE..."},
203  {NULL, 0, 0, 0, NULL, NULL, NULL}};
204 
205  option_context =
206  g_option_context_new ("- standalone NASL interpreter for OpenVAS");
207  g_option_context_add_main_entries (option_context, entries, NULL);
208  if (!g_option_context_parse (option_context, &argc, &argv, &error))
209  {
210  g_print ("%s\n\n", error->message);
211  exit (0);
212  }
213  g_option_context_free (option_context);
214  /*--------------------------------------------
215  Command-line options
216  ---------------------------------------------*/
217 
218  if (display_version)
219  {
220  printf ("openvas-nasl %s\n", nasl_version ());
221  if (debug_tls)
222  {
223  printf ("gnutls %s\n", gnutls_check_version (NULL));
224  printf ("libssh %s\n", ssh_version (0));
225  printf ("gpgme %s\n", gpgme_check_version (NULL));
226  }
227  else
228  putchar ('\n');
229  printf ("Copyright (C) 2002 - 2004 Tenable Network Security\n");
230  printf ("Copyright (C) 2022 Greenbone Networks GmbH\n\n");
231  exit (0);
232  }
233  if (nasl_debug)
234  global_nasl_debug = 1;
235  mode |= NASL_COMMAND_LINE;
236  if (signing_mode)
237  mode |= NASL_ALWAYS_SIGNED;
238  if (description_only)
239  mode |= NASL_EXEC_DESCR;
240  if (do_lint)
241  mode |= NASL_LINT;
242  if (parse_only)
243  mode |= NASL_EXEC_PARSE_ONLY;
244  if (trace_file)
245  {
246  if (!strcmp (trace_file, "-"))
247  nasl_trace_fp = stderr;
248  else
249  {
250  FILE *fp = fopen (trace_file, "w");
251  if (fp == NULL)
252  {
253  perror (optarg);
254  exit (2);
255  }
256  setvbuf (fp, NULL, _IOLBF, BUFSIZ);
257  nasl_trace_fp = fp;
258  }
259  }
260 
261  gcrypt_init ();
262  openvas_SSL_init ();
263  if (!nasl_filenames)
264  {
265  fprintf (stderr, "Error. No input file(s) specified !\n");
266  exit (1);
267  }
268 
269  if (!(mode & (NASL_EXEC_PARSE_ONLY | NASL_LINT)) && geteuid ())
270  {
271  fprintf (stderr, "** WARNING : packet forgery will not work\n");
272  fprintf (stderr, "** as NASL is not running as root\n");
273  }
274  signal (SIGPIPE, SIG_IGN);
275 
276  if (source_iface && gvm_source_iface_init (source_iface))
277  {
278  fprintf (stderr, "Erroneous network source interface: %s\n",
279  source_iface);
280  exit (1);
281  }
282  if (debug_tls)
283  {
284  gnutls_global_set_log_function (my_gnutls_log_func);
285  gnutls_global_set_log_level (debug_tls);
286  }
287 
288  if (!target)
289  target = g_strdup (default_target);
290 
291  hosts = gvm_hosts_new (target);
292  if (!hosts)
293  {
294  fprintf (stderr, "Erroneous target %s\n", target);
295  exit (1);
296  }
297  unresolved = gvm_hosts_resolve (hosts);
298  while (unresolved)
299  {
300  g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
301  unresolved = unresolved->next;
302  }
303  g_slist_free_full (unresolved, g_free);
304  g_free (target);
305 
306  // for absolute and relative paths
307  add_nasl_inc_dir ("");
308  if (include_dir != NULL)
309  {
310  add_nasl_inc_dir (include_dir);
311  }
312 
313  prefs_config (config_file ? config_file : OPENVAS_CONF);
314 
315  if (prefs_get ("vendor_version") != NULL)
316  vendor_version_set (prefs_get ("vendor_version"));
317 
318  if (port_range != NULL)
319  {
320  prefs_set ("port_range", port_range);
321  g_free (port_range);
322  }
323 
324  if (with_safe_checks)
325  prefs_set ("safe_checks", "yes");
326 
327  pos = 0; // Append the item on the right side of the list
328  while ((host = gvm_hosts_next (hosts)))
329  {
330  struct in6_addr ip6;
331  kb_t kb;
332  int rc;
333 
334  if (prefs_get_bool ("expand_vhosts"))
335  gvm_host_add_reverse_lookup (host);
336  gvm_vhosts_exclude (host, prefs_get ("exclude_hosts"));
337  gvm_host_get_addr6 (host, &ip6);
338  rc = kb_new (&kb, prefs_get ("db_address") ? prefs_get ("db_address")
339  : KB_PATH_DEFAULT);
340  if (rc)
341  exit (1);
342 
343  set_main_kb (kb);
344  script_infos = init (&ip6, host->vhosts, kb);
345  for (int i = 0; nasl_filenames[i] != NULL; i++)
346  {
347  script_infos->name = nasl_filenames[i];
348  if (both_modes || with_safe_checks)
349  {
350  nvti_t *nvti = parse_script_infos (script_infos);
351  if (!nvti)
352  {
353  err++;
354  continue;
355  }
356  else if (with_safe_checks
357  && !nvti_category_is_safe (nvti_category (nvti)))
358  {
359  printf ("%s isn't safe\n", nasl_filenames[i]);
360  nvti_free (nvti);
361  err++;
362  continue;
363  }
364  nvti_free (nvti);
365  }
366  if (kb_values)
367  {
368  gchar **kb_values_aux = kb_values;
369  while (*kb_values_aux)
370  {
371  gchar **splits = g_strsplit (*kb_values_aux, "=", -1);
372  if (splits[2] || !splits[1])
373  {
374  fprintf (stderr, "Erroneous --kb entry %s\n",
375  *kb_values_aux);
376  exit (1);
377  }
378  kb_item_add_str_unique (kb, splits[0], splits[1], 0, pos);
379  kb_values_aux++;
380  g_strfreev (splits);
381  }
382  }
383 
384  if (exec_nasl_script (script_infos, mode) < 0)
385  err++;
386  }
387  g_free (script_infos->globals);
388  g_free (script_infos);
389  kb_delete (kb);
390  }
391 
392  if (nasl_trace_fp != NULL)
393  fflush (nasl_trace_fp);
394 
395  gvm_hosts_free (hosts);
396  return err;
397 }
script_infos::standalone
int standalone
Definition: scanneraux.h:39
nvti_category_is_safe
static int nvti_category_is_safe(int category)
Checks that an NVT category is safe.
Definition: nasl.c:109
script_infos::ip
struct in6_addr * ip
Definition: scanneraux.h:37
script_infos
Definition: scanneraux.h:29
ACT_FLOOD
@ ACT_FLOOD
Definition: nvt_categories.h:33
script_infos::key
kb_t key
Definition: scanneraux.h:32
add_nasl_inc_dir
int add_nasl_inc_dir(const char *)
Adds the given string as directory for searching for includes.
Definition: nasl_grammar.tab.c:2539
script_infos::name
char * name
Definition: scanneraux.h:35
script_infos::nvti
nvti_t * nvti
Definition: scanneraux.h:33
exec.h
ACT_DENIAL
@ ACT_DENIAL
Definition: nvt_categories.h:31
NASL_EXEC_DESCR
#define NASL_EXEC_DESCR
Definition: nasl.h:45
openvas_SSL_init
int openvas_SSL_init()
Initializes SSL support.
Definition: network.c:341
script_infos::globals
struct scan_globals * globals
Definition: scanneraux.h:30
nasl_trace_fp
FILE * nasl_trace_fp
Definition: exec.c:357
nasl_lex_ctxt.h
nasl.h
script_infos::oid
char * oid
Definition: scanneraux.h:34
scan_globals
Definition: scanneraux.h:19
NASL_COMMAND_LINE
#define NASL_COMMAND_LINE
Definition: nasl.h:48
main
int main(int argc, char **argv)
Main of the standalone nasl interpreter.
Definition: nasl.c:138
host
Host information, implemented as doubly linked list.
Definition: hosts.c:37
parse_script_infos
static nvti_t * parse_script_infos(struct script_infos *infos)
Definition: nasl.c:83
script_infos::vhosts
GSList * vhosts
Definition: scanneraux.h:38
set_main_kb
void set_main_kb(kb_t kb)
sets the shared database between ospd and openvas as a main_kb for further usage. @description this s...
Definition: kb_cache.c:27
global_nasl_debug
int global_nasl_debug
Definition: plugutils.c:38
ACT_KILL_HOST
@ ACT_KILL_HOST
Definition: nvt_categories.h:32
NASL_ALWAYS_SIGNED
#define NASL_ALWAYS_SIGNED
Definition: nasl.h:47
exec_nasl_script
int exec_nasl_script(struct script_infos *script_infos, int mode)
Execute a NASL script.
Definition: exec.c:1614
gcrypt_init
static void gcrypt_init()
Initialize Gcrypt.
Definition: nasl.c:121
my_gnutls_log_func
static void my_gnutls_log_func(int level, const char *text)
Definition: nasl.c:53
vendor_version_set
void vendor_version_set(const gchar *version)
Set vendor version.
Definition: vendorversion.c:26
NASL_EXEC_PARSE_ONLY
#define NASL_EXEC_PARSE_ONLY
Definition: nasl.h:46
hosts
static struct host * hosts
Definition: hosts.c:49
ACT_DESTRUCTIVE_ATTACK
@ ACT_DESTRUCTIVE_ATTACK
Definition: nvt_categories.h:30
nasl_version
char * nasl_version(void)
Definition: nasl_init.c:542
init
static struct script_infos * init(struct in6_addr *ip, GSList *vhosts, kb_t kb)
Definition: nasl.c:61
NASL_LINT
#define NASL_LINT
Definition: nasl.h:49