#TRUSTED 5382a0be2f39bb0b1127d820a8f8c901d6c8aefefa5c2df8e4abfa4650135382252e0be1cef8bdab26491e2e43e2368289f4e668216f4d9cca40a4622a6fcb08c4b5064418def1e255619e98a3d7aab9c7960a6c298442225892e94dde457609f2fc3ad3b0e904d8f8796fcbd3b8208db42c7b17aa86f73f1126d24ada6883eaabd5d60d5ae5ff93989d1638c20d2792853eb5eb021b7282b3716c62b0509895d3a50e64eee12680f2cd81e4a128ae3a346822b4e4dedb39ccb12c9e702e687e0b38db3c6d8f385d452f368c615effbbc4eff470c5dd3c17bba1aa3b44770bfde648e9fb9d5cf99d1de27c4836a7da81381d88f5c049719a157af8e894f57506bf13c53c7ec8bdb84638ce2ba7aabfde31ebe5d17e2fdcd971db12d30c4ed29fdf6ed7f7dbb8e0c9a08746b83305526b6328416f6de4512ea14e1543ed80fa27b0f42f57c3936fed40f86f8a80beb5a2a849a5d16ac2dec9d46d002bf5adafdce3e23a05dab948e20f177192556fd54f53a53a98fc2ec22857772dac303bba6ab162084ac39f6fd4c4a76f899acf2ad98dfdbe1de3d71da7c84368a8af0200b98414ffd4b4fa5d6aee9775793d5926527b574937eb1458605e55ffc88a947cc3f222ba5a9edf9584513ff00e2808bddacfa7233465af72e8f7386fb1956ad4d2bc803d915bd82e5f198ade0dcdc9844e2086e9730294763a94b18716ab6a9780
#
# This script was written by Michel Arboi <arboi@alussinan.org>
#
# GPL
#

if ( ! defined_func("pread") ) exit(0);



if(description)
{
 script_id(14272);
 script_version ("1.9");
 name["english"] = "Netstat 'scanner'";
 script_name(english:name["english"]);
 
 desc["english"] = "
This plugin runs netstat on the remote machine to find open ports.
See the section 'plugins options' to configure it

Risk factor : None";

 script_description(english:desc["english"]);
 
 summary["english"] = "Find open ports with netstat";
 script_summary(english:summary["english"]);
 
 script_category(ACT_SCANNER);
 
 script_copyright(english:"This script is Copyright (C) 2004 Michel Arboi");
 family["english"] = "Port scanners";
 family["francais"] = "Scanners de ports";
 script_family(english:family["english"], francais:family["francais"]);

 script_add_preference(name: "Check found ports (intrusive)", type: "checkbox", value: "no");
 script_dependencies("ping_host.nasl", "ssh_settings.nasl");
 exit(0);
}

#
include("ssh_func.inc");

buf = "";

# On the local machine, just run the command
if (islocalhost())
  buf = pread(cmd: "netstat", argv: make_list("netstat", "-a", "-n"));
else
{
# First try the netstat service, just in case
 s = open_sock_tcp(15);
 if (s)
 {
   while (r = recv(socket: s, length: 4096))
     buf += r;
   close(s);
 }
# Then try SSH if the result is not OK
 if ("LISTEN" >!< buf)
 {
 sock = ssh_login_or_reuse_connection();
 if (! sock)  exit(0);

 buf = ssh_cmd(socket:sock, cmd:"cmd /c netstat -an", timeout:60);

 if ("LISTENING" >!< buf && "0.0.0.0:0" >!< buf && "*.*" >!< buf)
 {
 buf = ssh_cmd(socket:sock, cmd:"netstat -a -n", timeout:60);
 ssh_close_connection();
 if (! buf) { display("could not send command\n"); exit(0); }
 }
}
}

# display(buf);
ip = get_host_ip();
lines = split(buf);
n = max_index(lines);
if (n == 0) n = 1; i = 0;
scanner_status(current: 0, total: n);
scanned = 0;
check = script_get_preference("Check found ports (intrusive)");
check = ("yes" >< check);	# "no" by default

identd_n = 0; identd_err = 0;

foreach line (lines)
{
  # Windows
  v = eregmatch(pattern: '^[ \t]+(TCP|UDP)[ \t]+([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+):([0-9]+)[ \t]+(0\\.0\\.0\\.0:0|\\*\\.\\*)[ \t]+', string: line, icase: 0);
  # Unix
  if (isnull(v))
   v = eregmatch(pattern: '^(tcp|udp)[46]?[ \t]+.*[ \t]+(\\*|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)[:.]([0-9]+)[ \t]+(.*[ \t]+LISTEN|0\\.0\\.0\\.0:\\*)', string: line, icase: 1);
  if (isnull(v))
  # tcp 0 0 :::22   :::*    LISTEN
  # tcp 0 0 ::1:25  :::*    LISTEN (1 = localhost)
  v = eregmatch(pattern: '^(tcp|udp)[ \t]+.*[ \t]+(:::)([0-9]+)[ \t]+.*[ \t]+LISTEN', string: line, icase: 1);

  # Solaris 9
  if (isnull(v))
  {
    if (last_seen_proto)
    {
      if (last_seen_proto == 'udp')
        v = eregmatch(pattern: '^[ \t]*(\\*|[0-9.]+)\\.([0-9]+)[ \t]+Idle', string: line);
      else
        v = eregmatch(pattern: '^[ \t]*(\\*|[0-9.]+)\\.([0-9]+)[ \t]+\\*\\.\\*[ \t]+.*(Idle|LISTEN)', string: line);
      
      if (! isnull(v))
      {
        # "Fix" array
        v[3] = v[2]; v[2] = v[1]; v[1] = last_seen_proto;
      }
    }
    if (isnull(v))
    {
      v = eregmatch(pattern: '^(TCP|UDP): +IPv4[ \t\r\n]*$', string: line);
      if (!isnull(v))
      {
        last_seen_proto = tolower(v[1]);
        v = NULL;
      }
    }
  }
  

  if (!isnull(v))
  {
    if (check && defined_func("get_source_port"))
      identd_soc = open_sock_tcp(113);
    proto = tolower(v[1]);
    addr = v[2];
    port = v[3];
    if (addr == "0.0.0.0" || addr == ip || addr == ":::" || addr == '*')
    {
      if (check && proto == "tcp")
      {
        soc = open_sock_tcp(port);
        if (soc)
        {
          scanner_add_port(proto: proto, port: port);
	  if (identd_soc)
	  {
	    req = strcat(port, ',', get_source_port(soc), '\r\n');
	    if (send(socket: identd_soc, data: req) <= 0)
	    {
	      # Let's be quick: do not reopen the socket if an error occurs
	      # Another plugin with complete the job
	      close(identd_soc);
	      identd_soc = NULL;
	      identd_err ++;
	      id = NULL;
	    }
	    else
	      id = recv_line(socket: identd_soc, length: 1024);
	    if (id)
	    {
	      ids = split(id, sep: ':');
	      if ("USERID" >< ids[1])
              {
		identd_n ++;
		set_kb_item(name: "Ident/tcp/"+port, value: ids[3]);
		security_note(port: port, 
data: 'identd reveals that this service is running as user '+ids[3]);
	      }
	    }
	  }
          close(soc);
        }
      }
      else
      scanner_add_port(proto: proto, port: port);
      # display(proto, "\t", port, "\n");
    }
    scanned ++;
  }
  scanner_status(current: i++, total: n);
}

if (identd_soc) close(identd_soc);

if (scanned)
{
 set_kb_item(name: "Host/scanned", value: TRUE);
 set_kb_item(name: "Host/udp_scanned", value: TRUE);
 if (identd_n && ! identd_err)
   set_kb_item(name: "Host/ident_scanned", value: TRUE);
}

scanner_status(current: n, total: n);
exit(0);
