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

📄 nessus_tcp_scanner.c

📁 漏洞扫描源码,可以扫描linux,windows,交换机路由器
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * Copyright (C) 2004 Michel Arboi <mikhail@nessus.org> * * 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. * */#include <includes.h>#ifdef LINUX#include <netinet/tcp.h>#include <netinet/ip.h>#endif#include <limits.h>#include <math.h>#if defined STANDALONE && defined __STDC__#include <stdarg.h>#endif#ifndef ipci#define ipci() #define ipcd()#define ipcc() ( 0 == 1 )#define cct(x,y) ( 1 == 1 )#endif#if ! defined FD_SETSIZE || FD_SETSIZE > 1024#define GRAB_MAX_SOCK		1024#else#define GRAB_MAX_SOCK		FD_SETSIZE#endif#if ! defined FD_SETSIZE || FD_SETSIZE > 32#define GRAB_MIN_SOCK		32#else#define GRAB_MIN_SOCK		FD_SETSIZE#warn "FD_SETSIZE is lower than 32"#endif#if ! defined FD_SETSIZE || FD_SETSIZE > 128#define GRAB_MAX_SOCK_SAFE	128#else#define GRAB_MAX_SOCK_SAFE	FD_SETSIZE#warn "FD_SETSIZE is lower than 128"#endif#define MAX_PASS_NB	16#ifndef MAXINT#define MAXINT 0x7fffffffL#endif/* MA 2006-09-29 * As far as I know... * RANDOMIZE_PORTS does not have any bad side effect. * (we do not really "randomize" ports, we use an increment > 1) * RST_RATE_LIMIT may trigger wrongly on a slow link. * DETECT_FIREWALL may overload a slow link */#define RANDOMIZE_PORTS_TXT	"Scan ports in random order"#define RST_RATE_LIMIT_TXT	"Detect RST rate limitation"#define DETECT_FIREWALL_TXT	"Detect firewall"#define NET_CONGESTION_TXT	"Network congestion detection"#define RANDOMIZE_PORTS_OPT	(1 << 0)#define RST_RATE_LIMIT_OPT	(1 << 1)#define DETECT_FIREWALL_OPT	(1 << 2)#define NET_CONGESTION_OPT	(1 << 3)#if ! defined STANDALONEPlugExport int plugin_init(struct arglist * desc){ plug_set_id(desc, 10335); plug_set_version(desc, "$Revision: 1.65 $");             plug_set_name(desc, "Nessus TCP scanner", NULL); plug_set_summary(desc, "Look for open TCP ports & services banners", NULL); plug_set_description(desc, "\This plugin is a classical TCP port scanner\n\It shall be reasonably quick even against a firewalled target.\n\\n\Once a TCP connection is open, it grabs any available banner\n\for the service identification plugins\n\\n\Note that TCP scanners are more intrusive than \n\SYN (half open) scanners\", NULL);  plug_set_copyright(desc, "(C) 2004 Michel Arboi <mikhail@nessus.org>", NULL); plug_set_category(desc, ACT_SCANNER); plug_set_family(desc, "Scanners de ports", "francais"); plug_set_family(desc, "Port scanners", NULL); add_plugin_preference(desc, RANDOMIZE_PORTS_TXT, PREF_CHECKBOX, "yes"); add_plugin_preference(desc, RST_RATE_LIMIT_TXT, PREF_CHECKBOX, "yes"); add_plugin_preference(desc, DETECT_FIREWALL_TXT, PREF_CHECKBOX, "yes");#ifdef TCP_INFO add_plugin_preference(desc, NET_CONGESTION_TXT, PREF_CHECKBOX, "yes");#endif plug_set_dep(desc, "ping_host.nasl"); return(0);}#endiftypedef struct {  int			fd;  struct timeval	tictac;		/* open time */  unsigned short	port;  unsigned char		state;} grab_socket_t;#define DIFFTV(t1,t2)	(t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)#define DIFFTVu(t1,t2)	((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))#define GRAB_SOCKET_UNUSED	0#define GRAB_SOCKET_OPENING	1#define GRAB_SOCKET_OPEN	2#define GRAB_PORT_UNKNOWN	0#define GRAB_PORT_CLOSED	1#define GRAB_PORT_OPEN		2#define GRAB_PORT_SILENT	3#define GRAB_PORT_REJECTED	4#define GRAB_PORT_NOT_TESTED	254#define GRAB_PORT_TESTING	255/* Increase if you want verbose logs * This value is overwritten by the NESSUS_TCP_SCANNER_DEBUG environment  * variable, if it is set */static int	debug_level = 0;/* * RTT is always estimated (at least, the maximum is remembered) * If you want to enable the "statistics", define COMPUTE_RTT and link  * the plugin with libm (we need sqrt) */#define COMPUTE_RTT/* Linux re-sends a SYN packet after 3 s. On some other OSs, this value  * can be configured. e.g. http://support.microsoft.com/kb/223450/EN-US/ * Anyway, I don't think that we can really have a RTT bigger than 2 s * I set 2.5 s just in case... * MA 2006-09-29 * a random value is added to the maximum RTT to get the timeout * This value is 100 ms at most. * In ANY case, the total timeout MUST be inferior to the retransmission  * interval. Otherwise, performances will collapse against some firewalled  * machines. */#if defined TCP_INFO#define MAX_SANE_RTT (2900 * 1000) /*  2.9 s */#else#define MAX_SANE_RTT (2500*1000)	/* micro-seconds => 2.5 s */#endifstatic int#ifdef __GNUC____attribute__((format(printf, 3, 4)))#endifdebug_printf(const void		 *pia, /* may be NULL */	     int		debug,	     const char	*fmt,	     ...){  char		buf[256];  int		i;  va_list	ap;  if (debug < 0 || debug > debug_level) return 0;  va_start (ap, fmt);  vsnprintf(buf, sizeof(buf), fmt, ap);  buf[sizeof(buf)-1] = '\0';  va_end (ap);  /* Remove the \n at the end */  for (i = 0; i < sizeof(buf); i ++)    if (buf[i] == '\0')      break;  if (i > 0 && buf[i-1] == '\n')    buf[i-1] = '\0';      if (pia == NULL)    fprintf(stderr, "nessus_tcp_scanner[%d]: %s\n", getpid(), buf);  else    fprintf(stderr, "nessus_tcp_scanner(%s)[%d]: %s\n", 	    pia ? inet_ntoa(*(const struct in_addr*) pia):"ipv6", getpid(), buf);  return 0;} /* * On Linux, is_sane_rtt checks if there have been retransmits or not. * It also returns congestion detected by the kernel. * On other systems where TCP_INFO is not available, or if the getsockopt call * failed, it only checks if rtt < MAX_SANE_RTT */static intis_sane_rtt(int rtt, int s, int *congestion){#if defined TCP_INFO  struct   tcp_info	ti;  int			e;  socklen_t		len = sizeof(ti);  e = getsockopt(s, IPPROTO_TCP, TCP_INFO, &ti, &len);  if (e >= 0 && len == sizeof(ti))    {      debug_printf(NULL, 3, "tcpi_retransmits=0x%x tcpi_unacked=%u tcpi_ca_state=0x%x tcpi_rtt=%u tcpi_rttvar=%u x=%d\n", (unsigned) ti.tcpi_retransmits, ti.tcpi_unacked, (unsigned) ti.tcpi_ca_state, ti.tcpi_rtt, ti.tcpi_rttvar, rtt);      if (congestion != NULL)	*congestion += (ti.tcpi_ca_state & (1 << TCP_CA_CWR)) != 0;    return ti.tcpi_retransmits == 0;    }  if (e < 0)    {      if (errno != EBADF && debug_level > 0)	perror("nessus_tcp_scanner->getsockopt(TCP_INFO)");    }  else    debug_printf(NULL, 1, "getsockopt(TCP_INFO)=%d != %d\n",		 len, sizeof(ti));#endif  return rtt < MAX_SANE_RTT;}/* * If SO_LINGER was not set, my_socket_close calls shutdown to try to speed * up the close process */static intmy_socket_close(int s){#ifndef SO_LINGER  if (shutdown(s, 2) < 0)    if (debug_level > 0)      perror("nessus_tcp_scanner->shutdown");#endif  if ( s >= 0 ) ipcd();  return close(s);}/* Just a glue function to avoid ugly #ifdef in the main code */static intset_so_linger(int s){#ifdef SO_LINGER  struct linger	l;  l.l_onoff = 0; l.l_linger = 0;  if (setsockopt(s, SOL_SOCKET,  SO_LINGER,  &l, sizeof(l)) < 0)    {      perror("nessus_tcp_scanner->setsockopt(SO_LINGER)");      return -1;    }#endif  return 0;}static intset_nonblock(int s){  int	x;  if ((x = fcntl(s, F_GETFL)) < 0)    {      perror("nessus_tcp_scanner->fcntl(F_GETFL)");      return -1;    }  if (fcntl(s, F_SETFL, x | O_NONBLOCK) < 0)    {      perror("nessus_tcp_scanner->fcntl(F_SETFL)");      return -1;    }  return 0;}/*  * Linux can set IP TOS field from userland. This is probably not very useful, * as IP TOS (RFC791) is obsoleted by RFC2474, but some QoS systems may * still sort packets according to this field.  * RFC3168 deprecates IPTOS_MINCOST, as it conflicts with  * the "ECN capable" flags  */static intset_ip_tos(int s){  int	x;#if defined LINUX && defined IPTOS_RELIABILITY  x = IPTOS_RELIABILITY;  if (setsockopt(s, SOL_IP, IP_TOS, &x, sizeof(x)) < 0)    {      perror("nessus_tcp_scanner->setsockopt(IP_TOS,IPTOS_RELIABILITY");      return -1;    }#endif  return 0;}static int std_port(int port){  const char	*name;  extern char*	nessus_get_svc_name();  if (port < 1 || port > 65535) return 0;  name = nessus_get_svc_name(port, NULL);  if  (name == NULL || strcmp(name, "unknown") == 0)    return 0;  debug_printf(NULL, 3, "std_port(%d)=%s\n", port, name != NULL ? name : "(null)");  return 1;}/* * double_check_std_ports resets silent (filtered) standard ports to  * "to be tested" state. * (standard ports = those from nessus-services, which are included in the * "default" port range) * Return value: * Number of filtered or unknown ports; and number of "rejected" ports in an * auxilliary pointer */static intdouble_check_std_ports(unsigned char* ports_states, int *rejected){  int	port, tbd_nb = 0;  if (rejected != NULL) (*rejected) = 0;  for (port = 1; port <= 65535; port ++)    if (ports_states[port] == GRAB_PORT_UNKNOWN)      {	debug_printf(NULL, 0, "bug in double_check_std_ports! Unknown port %d status\n", port);	tbd_nb ++;      }    else if (std_port(port)) {      if (ports_states[port] == GRAB_PORT_SILENT)	{	  ports_states[port] = GRAB_PORT_UNKNOWN;	  tbd_nb ++;	}      else if (ports_states[port] == GRAB_PORT_REJECTED)	{	  if (rejected != NULL) (*rejected) ++;	}    }  debug_printf(NULL, 1, "double_check_std_ports found %d dropped standard ports\n", tbd_nb);  return tbd_nb;}static intget_ping_rtt(const struct in_addr *pia /* for debug only, may be NULL */,	     struct arglist *desc){  char		*k;  int		type = 0, ping_rtt = 0;  k = plug_get_key(desc, "/tmp/ping/RTT", &type);  if (type == ARG_STRING && k != NULL)    ping_rtt = atoi(k);  else if (type == ARG_INT)    ping_rtt = (int) k;  else if (type >= 0)    debug_printf(pia, 0, "unknown key type %d\n", type);  if (ping_rtt < 0 || ping_rtt > MAX_SANE_RTT)    ping_rtt = 0;  else    debug_printf(pia, 1, "ping_rtt=%g s\n", ping_rtt / 1e6);  return ping_rtt;}static intget_port_range(const char *portrange, 	       unsigned char *ports_states /* Will be set */){  int			i, n, untested_ports_nb = 0;  unsigned short	*nums = (unsigned short*)getpts((char*)portrange, &n);  if (nums == NULL )    {      debug_printf(NULL, 0, "nessus_tcp_scanner: getpts returns NULL. Fix your Nessus installation!\n");      return -1;    }  for (i = 0; i < n; i ++)     {      ports_states[nums[i]] = GRAB_PORT_UNKNOWN;      untested_ports_nb ++;    }  /* Do *not* free nums */  return untested_ports_nb;}/* * Double-check pass will disrupt our counters * Rather that saving old variables & restoring them on some branches of code, * it is safer to recount everything. * We need to go through the whole array of ports to reset the status of  * silent (filtered) ports to unknown/"to be tested", so this function call  * is not expensive */static voidrecount_ports(unsigned char	*ports_states,	      int		retest,	      int		*open, 	      int		*closed, 	      int		*dropped,	      int		*rejected,	      int		*untested){  int	i;  *dropped = *rejected = *open = *closed = *untested = 0;  for (i = 1; i <= 65535; i ++)    switch(ports_states[i])      {      case GRAB_PORT_SILENT:	if (retest)	  {	    (*untested) ++;	    ports_states[i] = GRAB_PORT_UNKNOWN;	  }	else	  (*dropped) ++;	break;      case GRAB_PORT_REJECTED:	(*rejected) ++;	break;      case GRAB_PORT_OPEN:	(*open) ++;	break;      case GRAB_PORT_CLOSED:	(*closed) ++;	break;      case GRAB_PORT_UNKNOWN:	(*untested) ++;	break;      }}/* * The main function */static intbanner_grab(const struct in_addr *pia, #ifdef IPV6_SUPPORT            const struct sockaddr_in6 * pia6, #endif	    const char* portrange, 

⌨️ 快捷键说明

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