⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasl_cmd_exec.c

📁 大国补丁后的nessus2.2.8的源代码
💻 C
字号:
/* Nessus Attack Scripting Language  * * Copyright (C) 2002 - 2004 Tenable Network Security * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /*  * This file contains all the "unsafe" functions found in NASL  */#include <includes.h>#include "nasl_tree.h"#include "nasl_global_ctxt.h"#include "nasl_func.h"#include "nasl_var.h"#include "nasl_lex_ctxt.h"#include "exec.h"  #include "strutils.h"#include "nasl_cmd_exec.h"#include "nasl_debug.h"static  pid_t pid = 0;static  void (*old_sig_t)() = NULL, (*old_sig_i)() = NULL, (*old_sig_c) = NULL;static voidsig_h(){  if (pid > 0)    (void) kill(pid, SIGKILL);}static void	sig_c(){  if (pid > 0)    (void) waitpid(pid, NULL, WNOHANG);}tree_cell*nasl_pread(lex_ctxt * lexic){  tree_cell	*retc = NULL, *a;  anon_nasl_var	*v;  nasl_array	*av;  int		i, j, n, sz, sz2, cd, nice;  char		** args = NULL, *cmd, *str, *str2, buf[8192];  FILE		*fp;#ifdef MAXPATHLEN  char		cwd[MAXPATHLEN], newdir[MAXPATHLEN];#else  char		cwd[1024], newdir[1024];#endif if ( check_authenticated(lexic) < 0 ) return NULL;    if (pid != 0)    {      nasl_perror(lexic, "nasl_pread is not reentrant!\n");      return NULL;    }  a = get_variable_by_name(lexic, "argv");  cmd = get_str_local_var_by_name(lexic, "cmd");  if (cmd == NULL || a == NULL || (v = a->x.ref_val) == NULL)    {      nasl_perror(lexic, "pread() usage: cmd:..., argv:...\n");      return NULL;    }  nice = get_int_local_var_by_name(lexic, "nice", 0);    if (v->var_type == VAR2_ARRAY)    av = &v->v.v_arr;  else    {      nasl_perror(lexic, "pread: argv element must be an array (0x%x)\n",		  v->var_type);      return NULL;    }  cd = get_int_local_var_by_name(lexic, "cd", 0);  cwd[0] = '\0';  if (cd)    {      char	*p;      if (cmd[0] == '/')	{	  strncpy(newdir, cmd, sizeof(newdir)-1);	  p = strrchr(newdir, '/');	  if (p != newdir) *p = '\0';	}      else	{	  p = find_in_path(cmd, 0);	  if (p != NULL)	    strncpy(newdir, p, sizeof(newdir)-1);	  else	    {	      nasl_perror(lexic, "pread: '%s' not found in $PATH\n", cmd);	      return NULL;	    }	  	}      newdir[sizeof(newdir)-1] = '\0';      if (getcwd(cwd, sizeof(cwd)) == NULL)	{	  nasl_perror(lexic, "pread(): getcwd: %s\n", strerror(errno));	  *cwd = '\0';	}      if (chdir(newdir) < 0)	{	  nasl_perror(lexic, "pread: could not chdir to %s\n", newdir);	  return NULL;	}      if (cmd[0] != '/' && strlen(newdir) + strlen(cmd) + 1 < sizeof(newdir))	{	  strcat(newdir, "/");	  strcat(newdir, cmd);	  cmd = newdir;	}    }  if (av->hash_elt != NULL)    nasl_perror(lexic, "pread: named elements in 'cmd' are ignored!\n");  n = av->max_idx;  args = emalloc(sizeof(char**) * (n+2)); /* Last arg is NULL */  for (j= 0, i = 0; i < n; i ++)    {      str = (char*)var2str(av->num_elt[i]);      if (str != NULL)	args[j++] = estrdup(str);    }  args[j++] = NULL;  old_sig_t = signal(SIGTERM, sig_h);  old_sig_i = signal(SIGINT, sig_h);  old_sig_c = signal(SIGCHLD, sig_c);  fp = nessus_popen4((const char*)cmd, args, &pid, nice);  for (i = 0; i < n; i ++)    efree(&args[i]);  efree(&args);  if (fp != NULL)    {      sz = 0; str = emalloc(1);      errno = 0;      while ((n = fread(buf, 1, sizeof(buf), fp)) > 0 || errno == EINTR ) /* && kill(pid, 0) >= 0)*/	{          if ( errno == EINTR )           {           errno = 0;	   continue;	  }	  sz2 = sz + n;	  str2 = erealloc(str, sz2);	  if (str2 == NULL)	    {	      nasl_perror(lexic, "nasl_pread: erealloc failed\n");	      break;	    }	  str = str2;	  memcpy(str + sz, buf, n);	  sz = sz2;	}      if (ferror(fp) && errno != EINTR )	nasl_perror(lexic, "nasl_pread: fread(): %s\n", strerror(errno));      (void) nessus_pclose(fp, pid);      pid = 0;      if (*cwd != '\0')	if (chdir(cwd) < 0)	  nasl_perror(lexic, "pread(): chdir(%s): %s\n", cwd, strerror(errno));      retc = alloc_typed_cell(CONST_DATA);      retc->x.str_val = str;      retc->size = sz;    }  signal(SIGINT, old_sig_i);  signal(SIGTERM, old_sig_t);  signal(SIGCHLD, old_sig_c);  return retc;}tree_cell*nasl_find_in_path(lex_ctxt * lexic){  tree_cell	*retc;  char		*cmd; if ( check_authenticated(lexic) < 0 ) return NULL;  cmd = get_str_var_by_num(lexic, 0);  if (cmd == NULL)    {      nasl_perror(lexic, "find_in_path() usage: cmd\n");      return NULL;    }  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = (find_in_path(cmd, 0) != NULL);  return retc;}/* * Not a command, but dangerous anyway */tree_cell*nasl_fread(lex_ctxt * lexic){  tree_cell	*retc;  char		*fname;  struct stat	st;  char		*buf, *p;  int		alen, len, n;  FILE		*fp; if ( check_authenticated(lexic) < 0 ) return NULL;      fname = get_str_var_by_num(lexic, 0);  if (fname == NULL)    {      nasl_perror(lexic, "fread: need one argument (file name)\n");      return NULL;    }    if (stat(fname, &st) < 0)    {      nasl_perror(lexic, "fread: stat(%s): %s\n", fname, strerror(errno));      return NULL;    }  fp = fopen(fname, "r");  if (fp == NULL)    {      nasl_perror(lexic, "fread: %s: %s\n", fname, strerror(errno));      return NULL;    }  alen = st.st_size + 1;  buf = emalloc(alen);  if (buf == NULL)    {      nasl_perror(lexic, "fread: cannot malloc %d bytes\n", alen);      goto error;    }  len = 0;  while ((n = fread(buf + len, 1, alen - len, fp)) > 0)    {      len += n;      if (alen <= len)	{	  alen += 4096;	  p = erealloc(buf, alen);	  if (p == NULL)	    {	      nasl_perror(lexic, "fread: cannot realloc %d bytes\n", alen);	      goto error;	    }	  buf = p;	}    }  buf[len] ='\0';  if (alen > len+1)    {      p = erealloc(buf, len+1);      if (p != NULL) buf = p;    }  retc = alloc_typed_cell(CONST_DATA);  retc->size = len;  retc->x.str_val = buf;  fclose(fp);  return retc;   error:  efree(&buf);  fclose(fp);  return NULL;}/* * Not a command, but dangerous anyway */tree_cell*nasl_unlink(lex_ctxt * lexic){  char		*fname; if (check_authenticated(lexic) < 0) return NULL;      fname = get_str_var_by_num(lexic, 0);  if (fname == NULL)    {      nasl_perror(lexic, "unlink: need one argument (file name)\n");      return NULL;    }  if (unlink(fname) < 0)    {      nasl_perror(lexic, "unlink(%s): %s\n", fname, strerror(errno));      return NULL;    }  /* No need to return a value */  return FAKE_CELL;}/* Definitely dangerous too */tree_cell*nasl_fwrite(lex_ctxt * lexic){  tree_cell	*retc;  char		*content, *fname;  int		len, i, x;  FILE		*fp;  if (check_authenticated(lexic) < 0)    {      nasl_perror(lexic, "fwrite may only be called by an authenticated script\n");      return NULL;    }      content = get_str_local_var_by_name(lexic, "data");  fname = get_str_local_var_by_name(lexic, "file");  if (content == NULL || fname == NULL)    {      nasl_perror(lexic, "fwrite: need two arguments 'data' and 'file'\n");      return NULL;    }  len = get_var_size_by_name(lexic, "data");    fp = fopen(fname, "w");  if (fp == NULL)    {      nasl_perror(lexic, "fwrite: %s: %s\n", fname, strerror(errno));      return NULL;    }  for (i = 0; i < len; )    {      x = fwrite(content + i, 1, len - i, fp);      if (x > 0)	i += x;      else	{	  nasl_perror(lexic, "fwrite: %s: %s\n", fname, strerror(errno));	  (void) fclose(fp);	  unlink(fname);	  return NULL;	}    }  if (fclose(fp) < 0)    {      nasl_perror(lexic, "fwrite: %s: %s\n", fname, strerror(errno));      unlink(fname);      return NULL;    }  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = len;  return retc;}tree_cell*nasl_get_tmp_dir(lex_ctxt * lexic){  tree_cell	*retc;  char		*p, path[MAXPATHLEN];  int		warn = 0; if (check_authenticated(lexic) < 0) return NULL; snprintf(path, sizeof(path), "%s/nessus/tmp/", NESSUS_STATE_DIR); if (access(path, R_OK|W_OK|X_OK) < 0)     {     nasl_perror(lexic, "get_tmp_dir(): %s not available - check your Nessus installation\n", path);     return NULL;     }      retc = alloc_typed_cell(CONST_DATA); retc->x.str_val = strdup(path); retc->size = strlen(retc->x.str_val); return retc;}/* *  File access functions : Dangerous */tree_cell*nasl_file_stat(lex_ctxt * lexic){  tree_cell	*retc;  char		*fname;  struct stat	st;  if ( check_authenticated(lexic) < 0 ) return NULL;   fname = get_str_var_by_num(lexic, 0);  if (fname == NULL)    {      nasl_perror(lexic, "file_stat: need one argument (file name)\n");      return NULL;    }    if (stat(fname, &st) < 0)      return NULL;  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = (int)st.st_size;  return retc;}tree_cell*nasl_file_open(lex_ctxt * lexic){  tree_cell	*retc;  char		*fname, *mode;  int		fd;   int		imode;  if ( check_authenticated(lexic) < 0 ) return NULL;   fname = get_str_local_var_by_name(lexic, "name");  if (fname == NULL)    {      nasl_perror(lexic, "file_open: need file name argument\n");      return NULL;    }   mode = get_str_local_var_by_name(lexic, "mode");  if (mode == NULL)    {      nasl_perror(lexic, "file_open: need file mode argument\n");      return NULL;    }  if ( strcmp(mode, "r") == 0 ) 	imode = O_RDONLY;  else if ( strcmp(mode, "w") == 0 )	imode = O_WRONLY|O_CREAT;  else if ( strcmp(mode, "w+") == 0 )	imode = O_WRONLY|O_TRUNC|O_CREAT;   else if ( strcmp(mode, "a") == 0 )	imode = O_WRONLY|O_APPEND|O_CREAT;   else if ( strcmp(mode, "a+") == 0 )	imode = O_RDWR|O_APPEND|O_CREAT;  fd = open(fname, imode, 0600);  if ( fd < 0 )    {      nasl_perror(lexic, "file_open: %s: %s\n", fname, strerror(errno));      return NULL;    }  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = fd;  return retc;}tree_cell*nasl_file_close(lex_ctxt * lexic){  tree_cell	*retc;  int		fd;  if ( check_authenticated(lexic) < 0 ) return NULL;   fd = get_int_var_by_num(lexic, 0, -1);  if ( fd < 0 )    {      nasl_perror(lexic, "file_close: need file pointer argument\n");      return NULL;    }   if (close(fd) < 0)    {      nasl_perror(lexic, "file_close: %s\n", strerror(errno));      return NULL;    }  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = 0;  return retc;}tree_cell*nasl_file_read(lex_ctxt * lexic){  tree_cell	*retc;  char		*buf;  int		len;  int		fd;  int           flength;  int           n;  if ( check_authenticated(lexic) < 0 ) return NULL;   fd = get_int_local_var_by_name(lexic, "fp", -1);  if (fd < 0 )    {      nasl_perror(lexic, "file_read: need file pointer argument\n");      return NULL;    }   flength = get_int_local_var_by_name(lexic, "length", 0);  buf = emalloc(flength + 1);  if (buf == NULL)    {      nasl_perror(lexic, "file_read: cannot malloc %d bytes\n", flength);      goto error;    }  for ( n = 0 ; n < flength ; )  {    int e;   errno = 0;   e  = read(fd, buf + n, flength - n);   if ( e < 0 && errno == EINTR ) continue;   else if ( e <= 0 ) break;   else n += e;  }    retc = alloc_typed_cell(CONST_DATA);  retc->size = n;  retc->x.str_val = buf;  return retc; error:  efree(&buf);  return NULL;}tree_cell*nasl_file_write(lex_ctxt * lexic){  tree_cell	*retc;  char		*content;  int		len;  int		fd;  int 		n;  if ( check_authenticated(lexic) < 0 ) return NULL;  content = get_str_local_var_by_name(lexic, "data");  fd = get_int_local_var_by_name(lexic, "fp", -1);  if (content == NULL || fd < 0 )    {      nasl_perror(lexic, "file_write: need two arguments 'fp' and 'data'\n");      return NULL;    }  len = get_var_size_by_name(lexic, "data");   for ( n = 0 ; n < len ;  )  {    int e;   errno = 0;   e = write(fd, content + n ,len - n);   if ( e < 0 && errno == EINTR ) continue;   else if ( e <= 0 )      {      nasl_perror(lexic, "file_write: write() failed - %s\n", strerror(errno));      break;     }   else n += e ;  }     retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = n;  return retc;}tree_cell*nasl_file_seek(lex_ctxt * lexic){  tree_cell	*retc;  int		len;  int		fd;  int           foffset;  if ( check_authenticated(lexic) < 0 ) return NULL;  foffset = get_int_local_var_by_name(lexic, "offset", 0);  fd = get_int_local_var_by_name(lexic, "fp", -1);  if (fd < 0 )    {      nasl_perror(lexic, "file_seek: need one arguments 'fp'\n");      return NULL;    }  if ( lseek(fd, foffset, SEEK_SET) < 0 )    {      nasl_perror(lexic, "fseek: %s\n", strerror(errno));      return NULL;    }  retc = alloc_typed_cell(CONST_INT);  retc->x.i_val = 0;  return retc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -