OpenVAS Libraries  9.0.3
nasl.c
Go to the documentation of this file.
1 /* Nessus Attack Scripting Language
2  *
3  * Copyright (C) 2002 - 2005 Tenable Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2,
7  * as published by the Free Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
24 #include <signal.h> /* for SIGINT */
25 #include <string.h> /* for strlen */
26 #include <stdlib.h> /* for exit */
27 #include <unistd.h> /* for geteuid */
28 #include <libssh/libssh.h> /* for ssh_version */
29 #include <gnutls/gnutls.h> /* for gnutls_check_version */
30 #include <sys/wait.h>
31 
32 #include "../misc/network.h"
33 #include "../misc/vendorversion.h"
34 
35 #include "nasl.h"
36 #include "nasl_lex_ctxt.h"
37 #include "exec.h"
38 #include "../base/gpgme_util.h" /* for gpgme_check_version */
39 #include "../base/kb.h" /* for kb_new */
40 #include "../base/openvas_hosts.h" /* for openvas_hosts_* and openvas_host_* */
41 #include "../base/nvti.h"
42 #include "../misc/prefs.h" /* for prefs_get */
43 #include "../misc/nvt_categories.h"
44 
45 #include <gcrypt.h> /* for gcry_control */
46 #include <glib.h>
47 
48 #ifndef MAP_FAILED
49 #define MAP_FAILED ((void*)-1)
50 #endif
51 
52 
53 extern char *nasl_version (void);
54 extern int execute_instruction (struct arglist *, char *);
55 void exit_nasl (struct arglist *, int);
56 
57 
58 void
60 {
61  exit (0);
62 }
63 
64 static void
65 my_gnutls_log_func (int level, const char *text)
66 {
67  fprintf (stderr, "[%d] (%d) %s", getpid (), level, text);
68  if (*text && text[strlen (text) -1] != '\n')
69  putc ('\n', stderr);
70 }
71 
72 struct arglist *
73 init (char *hostname, struct in6_addr *ip, char *fqdn, kb_t kb)
74 {
75  struct arglist *script_infos = g_malloc0 (sizeof (struct arglist));
76 
77  arg_add_value (script_infos, "standalone", ARG_INT, (void *) 1);
78  prefs_set ("checks_read_timeout", "5");
79  arg_add_value (script_infos, "key", ARG_PTR, kb);
80 
81  arg_add_value (script_infos, "HOSTNAME", ARG_PTR,
82  host_info_init (hostname, ip, NULL, fqdn));
83 
84  return script_infos;
85 }
86 
87 extern FILE *nasl_trace_fp;
88 
89 static nvti_t *
90 parse_script_infos (const char *file, struct arglist *script_infos)
91 {
92  nvti_t *nvti;
93  char *oid;
95 
96  nvti = nvti_new ();
97  arg_add_value (script_infos, "NVTI", ARG_PTR, nvti);
98 
99  if (exec_nasl_script (script_infos, file, NULL, mode) < 0)
100  {
101  printf ("%s could not be loaded\n", file);
102  return NULL;
103  }
104  arg_del_value (script_infos, "NVTI");
105 
106  arg_del_value (script_infos, "OID");
107  oid = g_strdup (nvti_oid (nvti));
108  if (oid)
109  arg_add_value (script_infos, "OID", ARG_STRING, oid);
110 
111  return nvti;
112 }
113 
114 
122 static int
123 nvti_category_is_safe (int category)
124 {
125  if (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST
126  || category == ACT_FLOOD || category == ACT_DENIAL)
127  return 0;
128  return 1;
129 }
130 
134 static void
135 gcrypt_init ()
136 {
137  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
138  return;
139  gcry_check_version (NULL);
140  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
141  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
142  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
143  gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
144 }
145 
151 int
152 main (int argc, char **argv)
153 {
154  struct arglist *script_infos;
155  openvas_hosts_t *hosts;
156  openvas_host_t *host;
157  static gchar *target = NULL;
158  gchar *default_target = "127.0.0.1";
159  int mode = 0, n = 0, err = 0;
160  extern int global_nasl_debug;
161 
162  static gboolean display_version = FALSE;
163  static gboolean nasl_debug = FALSE;
164  static gboolean description_only = FALSE;
165  static gboolean both_modes = FALSE;
166  static gboolean parse_only = FALSE;
167  static gboolean do_lint = FALSE;
168  static gchar *trace_file = NULL;
169  static gchar *config_file = NULL;
170  static gchar *source_iface = NULL;
171  static gchar *vendor_version_string = NULL;
172  static gboolean with_safe_checks = FALSE;
173  static gboolean authenticated_mode = FALSE;
174  static gchar *include_dir = NULL;
175  static gchar **nasl_filenames = NULL;
176  static gchar **kb_values = NULL;
177  static int debug_tls = 0;
178  GError *error = NULL;
179  GOptionContext *option_context;
180  static GOptionEntry entries[] = {
181  {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
182  "Display version information", NULL},
183  {"debug", 'd', 0, G_OPTION_ARG_NONE, &nasl_debug,
184  "Output debug information to stderr.", NULL},
185  {"description", 'D', 0, G_OPTION_ARG_NONE, &description_only,
186  "Only run the 'description' part of the script", NULL},
187  {"both", 'B', 0, G_OPTION_ARG_NONE, &both_modes,
188  "Run in description mode before running the script.", NULL},
189  {"parse", 'p', 0, G_OPTION_ARG_NONE, &parse_only,
190  "Only parse the script, don't execute it", NULL},
191  {"lint", 'L', 0, G_OPTION_ARG_NONE, &do_lint,
192  "'lint' the script (extended checks)", NULL},
193  {"target", 't', 0, G_OPTION_ARG_STRING, &target,
194  "Execute the scripts against <target>", "<target>"},
195  {"trace", 'T', 0, G_OPTION_ARG_FILENAME, &trace_file,
196  "Log actions to <file> (or '-' for stderr)", "<file>"},
197  {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
198  "Configuration file", "<filename>"},
199  {"source-iface", 'e', 0, G_OPTION_ARG_STRING, &source_iface,
200  "Source network interface for established connections.",
201  "<iface_name>"},
202  {"vendor-version", '\0', 0, G_OPTION_ARG_STRING, &vendor_version_string,
203  "Use <string> as vendor version.", "<string>"},
204  {"safe", 's', 0, G_OPTION_ARG_NONE, &with_safe_checks,
205  "Specifies that the script should be run with 'safe checks' enabled",
206  NULL},
207  {"authenticated", 'X', 0, G_OPTION_ARG_NONE, &authenticated_mode,
208  "Run the script in 'authenticated' mode", NULL},
209  {"include-dir", 'i', 0, G_OPTION_ARG_STRING, &include_dir,
210  "Search for includes in <dir>", "<dir>"},
211  {"debug-tls", 0, 0, G_OPTION_ARG_INT, &debug_tls,
212  "Enable TLS debugging at <level>", "<level>"},
213  {"kb", 'k', 0, G_OPTION_ARG_STRING_ARRAY, &kb_values,
214  "Set KB key to vaue. Can be used multiple times", "<key=value>"},
215  {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &nasl_filenames,
216  "Absolute path to one or more nasl scripts", "NASL_FILE..."},
217  {NULL}
218  };
219 
220  option_context =
221  g_option_context_new ("- standalone NASL interpreter for OpenVAS");
222  g_option_context_add_main_entries (option_context, entries, NULL);
223  if (!g_option_context_parse (option_context, &argc, &argv, &error))
224  {
225  g_print ("%s\n\n", error->message);
226  exit (0);
227  }
228  g_option_context_free (option_context);
229  /*--------------------------------------------
230  Command-line options
231  ---------------------------------------------*/
232 
233  if (display_version)
234  {
235  printf ("openvas-nasl %s\n", nasl_version ());
236  if (debug_tls)
237  {
238  printf ("gnutls %s\n", gnutls_check_version (NULL));
239  printf ("libssh %s\n", ssh_version (0));
240  printf ("gpgme %s\n", gpgme_check_version (NULL));
241  }
242  else
243  putchar ('\n');
244  printf ("Copyright (C) 2002 - 2004 Tenable Network Security\n");
245  printf ("Copyright (C) 2013 Greenbone Networks GmbH\n\n");
246  exit (0);
247  }
248  if (nasl_debug)
249  global_nasl_debug = 1;
250  mode |= NASL_COMMAND_LINE;
251  if (authenticated_mode)
252  mode |= NASL_ALWAYS_SIGNED;
253  if (description_only)
254  mode |= NASL_EXEC_DESCR;
255  if (do_lint)
256  mode |= NASL_LINT;
257  if (parse_only)
258  mode |= NASL_EXEC_PARSE_ONLY;
259  if (trace_file)
260  {
261  if (!strcmp (trace_file, "-"))
262  nasl_trace_fp = stderr;
263  else
264  {
265  FILE *fp = fopen (trace_file, "w");
266  if (fp == NULL)
267  {
268  perror (optarg);
269  exit (2);
270  }
271  setvbuf (fp, NULL, _IOLBF, BUFSIZ);
272  nasl_trace_fp = fp;
273  }
274  }
275  if (with_safe_checks)
276  prefs_set ("safe_checks", "yes");
277 
278  gcrypt_init();
279  openvas_SSL_init ();
280  if (!nasl_filenames)
281  {
282  fprintf (stderr, "Error. No input file(s) specified !\n");
283  exit (1);
284  }
285 
286  if (vendor_version_string)
287  vendor_version_set (vendor_version_string);
288 
289 #ifndef _CYGWIN_
290  if (!(mode & (NASL_EXEC_PARSE_ONLY | NASL_LINT)) && geteuid ())
291  {
292  fprintf (stderr, "** WARNING : packet forgery will not work\n");
293  fprintf (stderr, "** as NASL is not running as root\n");
294  }
295  signal (SIGINT, sighandler);
296  signal (SIGTERM, sighandler);
297  signal (SIGPIPE, SIG_IGN);
298 #endif
299 
300  if (source_iface && openvas_source_iface_init (source_iface))
301  {
302  fprintf (stderr, "Erroneous network source interface: %s\n",
303  source_iface);
304  exit (1);
305  }
306  if (debug_tls)
307  {
308  gnutls_global_set_log_function (my_gnutls_log_func);
309  gnutls_global_set_log_level (debug_tls);
310  }
311 
312  if (!target)
313  target = g_strdup (default_target);
314 
315  hosts = openvas_hosts_new (target);
316  g_free (target);
317 
318  // for absolute and relative paths
319  add_nasl_inc_dir ("");
320  if (include_dir != NULL)
321  {
322  add_nasl_inc_dir (include_dir);
323  }
324 
325  prefs_config (config_file ?: OPENVASSD_CONF);
326  while ((host = openvas_hosts_next (hosts)))
327  {
328  struct in6_addr ip6;
329  char *hostname, *fqdn;
330  kb_t kb;
331  int rc;
332 
333  hostname = openvas_host_value_str (host);
334  if (openvas_host_get_addr6 (host, &ip6) == -1)
335  {
336  fprintf (stderr, "Couldn't resolve %s\n", hostname);
337  err++;
338  g_free (hostname);
339  continue;
340  }
341 
342  rc = kb_new (&kb, prefs_get ("kb_location") ?: KB_PATH_DEFAULT);
343  if (rc)
344  exit (1);
345 
346  fqdn = openvas_host_reverse_lookup (host);
347  script_infos = init (hostname, &ip6, fqdn ?: hostname, kb);
348  g_free (fqdn);
349  while (nasl_filenames[n])
350  {
351  pid_t pid;
352 
353  if (both_modes || with_safe_checks)
354  {
355  nvti_t *nvti = parse_script_infos (nasl_filenames[n],
356  script_infos);
357  if (!nvti)
358  {
359  err++;
360  n++;
361  continue;
362  }
363  else if (with_safe_checks
364  && !nvti_category_is_safe (nvti_category (nvti)))
365  {
366  printf ("%s isn't safe\n", nasl_filenames[n]);
367  nvti_free (nvti);
368  err++;
369  n++;
370  continue;
371  }
372  nvti_free (nvti);
373  }
374  if (kb_values)
375  {
376  while (*kb_values)
377  {
378  gchar **splits = g_strsplit (*kb_values, "=", -1);
379  if (splits[2] || !splits[1])
380  {
381  fprintf (stderr, "Erroneous --kb entry %s\n", *kb_values);
382  exit (1);
383  }
384  kb_item_add_str (kb, splits[0], splits[1]);
385  kb_values++;
386  g_strfreev (splits);
387  }
388  }
389 
390  if ((pid = fork ()) == 0)
391  {
392  if (exec_nasl_script (script_infos, nasl_filenames[n],
393  arg_get_value (script_infos, "OID"), mode) < 0)
394  exit (1);
395  else
396  exit (0);
397  }
398  else if (pid < 0)
399  {
400  fprintf (stderr, "fork(): %s\n", strerror (errno));
401  exit (1);
402  }
403  else
404  {
405  int status;
406  waitpid (pid, &status, 0);
407  if (status)
408  err++;
409  }
410  n++;
411  }
412  kb_delete (kb);
413  g_free (hostname);
414  }
415 
416  if (nasl_trace_fp != NULL)
417  fflush (nasl_trace_fp);
418 
419  openvas_hosts_free (hosts);
420  return err;
421 }
The structure for a single host object.
Definition: openvas_hosts.h:76
#define ARG_INT
Definition: arglists.h:40
#define err(x)
void nvti_free(nvti_t *n)
Free memory of a nvti structure.
Definition: nvti.c:162
gchar * openvas_host_value_str(const openvas_host_t *host)
Gets a host&#39;s value in printable format.
int execute_instruction(struct arglist *, char *)
void openvas_hosts_free(openvas_hosts_t *hosts)
Frees memory occupied by an openvas_hosts_t structure.
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition: nvti.c:151
#define NASL_EXEC_PARSE_ONLY
Definition: nasl.h:61
FILE * nasl_trace_fp
Definition: exec.c:386
The structure of a information record that corresponds to a NVT.
Definition: nvti.h:64
#define ACT_DENIAL
const char * oid
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition: nvti.c:483
int main(int argc, char **argv)
Main of the standalone nasl interpretor.
Definition: nasl.c:152
openvas_host_t * openvas_hosts_next(openvas_hosts_t *hosts)
Gets the next openvas_host_t from a openvas_hosts_t structure. The state of iteration is kept interna...
char * nasl_version(void)
Definition: nasl_init.c:724
#define ACT_FLOOD
struct arglist * init(char *hostname, struct in6_addr *ip, char *fqdn, kb_t kb)
Definition: nasl.c:73
int openvas_SSL_init()
Initializes SSL support.
Definition: network.c:376
const gchar * prefs_get(const gchar *key)
Get a string preference value via a key.
Definition: prefs.c:86
#define KB_PATH_DEFAULT
Default KB location.
Definition: kb.h:40
openvas_hosts_t * openvas_hosts_new(const gchar *hosts_str)
Creates a new openvas_hosts_t structure and the associated hosts objects from the provided hosts_str...
int exec_nasl_script(struct arglist *script_infos, const char *name, const char *oid, int mode)
Execute a NASL script.
Definition: exec.c:1711
#define NASL_COMMAND_LINE
Definition: nasl.h:63
void arg_add_value(struct arglist *arglst, const char *name, int type, void *value)
Definition: arglists.c:170
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:102
void sighandler()
Definition: nasl.c:59
void prefs_set(const gchar *key, const gchar *value)
Set a string preference value via a key.
Definition: prefs.c:133
#define NASL_EXEC_DESCR
Definition: nasl.h:60
#define ARG_PTR
Definition: arglists.h:39
void exit_nasl(struct arglist *, int)
void prefs_config(const char *config)
Apply the configs from given file as preferences.
Definition: prefs.c:155
#define NASL_LINT
Definition: nasl.h:64
#define ACT_DESTRUCTIVE_ATTACK
#define NASL_ALWAYS_SIGNED
Definition: nasl.h:62
The structure for Hosts collection.
Definition: openvas_hosts.h:92
#define ARG_STRING
Definition: arglists.h:38
int global_nasl_debug
Definition: plugutils.c:54
int openvas_host_get_addr6(const openvas_host_t *host, struct in6_addr *ip6)
Gives a host object&#39;s value as an IPv6 address. If the host type is hostname, it resolves the IPv4 ad...
void arg_del_value(struct arglist *args, const char *name)
Definition: arglists.c:358
#define ACT_KILL_HOST
int openvas_source_iface_init(const char *iface)
Initializes the source network interface name and related information.
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition: nvti.c:218
void * arg_get_value(struct arglist *args, const char *name)
Definition: arglists.c:252
void vendor_version_set(const gchar *version)
Set vendor version.
Definition: vendorversion.c:39
struct host_info * host_info_init(const char *name, const struct in6_addr *ip, const char *vhosts, const char *fqdn)
Initializes a host_info.
Definition: network.c:2544
int add_nasl_inc_dir(const char *)
Adds the given string as directory for searching for includes.
char * openvas_host_reverse_lookup(openvas_host_t *host)
Checks for a host object reverse dns lookup existence.