Lucene search
K

OS Identification and Installed Software Enumeration over SSH v2 (Using New SSH Library)

🗓️ 30 May 2017 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 1898 Views

OS Identification and Installed Software Enumeration over SSH v2 (Using New SSH Library

Code
#TRUSTED 29629e6229a3506304d98634756c7351b5ecc9a36d5fb577541461e82a18f78b1fecbeda9e83b30b2a0492d037f239daf0b46bdc1f6949de043c879680dee7caef5ad0a65b2971339e2f0d4ea4ab6753b1e4661ed1f5116c6af7f9549288bf7aae08bfff828e7966c0043ae3620cca82b52827401a26b6592ddea00d14494a4e4af141190f63bd2ae0db046ca3bbfaeb3b8b28d577470a733b45a3e184bdd0b30c0aa2d610ad51850ec80e265ecd38e9c70bc850d9da0a8f7b0085867a1ec8846366c9730b81e4cd6ca0152b3daf9b9f517ce27e807ab037813359d7065c064173dd8b1ba126b062c8329e97bec9a2248f13ad0d53badb11dd2d3aafbd26fd278ca77dcc55822417b9c72e7f48c7fd52ba5332cb84f43660490fa4a9a0affae43d12065e682edd3cd3c8edc3066e67842b14c26843dcd8b6951fec1a408aa8fd1588b234b6e97cfd54f2b2370ad7b8f7936a2173234deac36f27b790f422662e57511236e41a4a7b359684d5c19ba99d9865f27e57e31e2c7378da3bdd132b56e3efbb7cfeae4efcc5a71bb4d7cb46718b0c5695cc66355dcecfc746bb72f727529ed235d20601e02f6d50def2b4e1575dfa80090799dab8e288e0b5e8bf979b9511544570b4a0f8d534b72ba9e54a760140d863b3d7dd3936aca5328246c4888f6c91b15b1fffeebcf97909854b05a1bb4e608074122933c4e15c22f79a8a6c
#TRUST-RSA-SHA256 b0b2e19e7d9987fa094df338bbe205bb0a8261488912da7d8fef63935006a80cb8fdd3c166c45ad74299f90ce14e8ff0dbc5b32c9f349d86e985a6bb1b2bb88c1b4b0090a5c9b6a9446482c190f79643d54b9a1aaea02d1bbce38fb0b774d1376c093d1d85d3c025288753e059a7173ba411125ba1d2048ddda3339436b5aa9db16cef93453c5aa38b91011bc94b09150e329587bc97184d0a7a0d922a2114730f82bf47c0269147b733f9a919834e263aee85ab40a1251afa8d39c0b51259d014661201c9d5d245c6b8cd8b15a57aa3c4f050ada2ae8cc34c48e884e49d198731065c8787d647aadafee90c0238f7fd4254acd69519a89a4c6ee958e4e083459a2087de6591cc64d00f1f21fdc9452b32499e27f7d33e6fd4e7ef33047b1144465ad682eee2602d6b3f3c13674e34e023f81895f2c67962ef082d73cb165f4cf47bede7e46176d65de4f791b0cd11e34063db2521230414ec3abef3ab826536811e8622d41e2ee88a9071b8f1b2436695bb52296ef8a1d283c370762be3d67b89832bf93d3bb84e36eea0eea768a07bd3a20a2ef0e8d06779065e7f9decaf048b76b2e13bfbe8475b3895b3ba0ab8573e68e181e003433643f776734d8498ca41668b6987e3100808513509fdfb77bf58278dde99e8579979b56b65f7cfbee92d50f679eea0072a80676de332961e4cf280fe94d95e8c49e41a1931f63501fd
#
# (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(97993);
  script_version("1.58");
  script_set_attribute(attribute:"plugin_modification_date", value:"2026/03/30");

  script_name(english:"OS Identification and Installed Software Enumeration over SSH v2 (Using New SSH Library)");
  script_summary(english:"Gathers OS and installed software information over SSH.");

  script_set_attribute(attribute:"synopsis", value:
"Information about the remote host can be disclosed via an
authenticated session.");
  script_set_attribute(attribute:"description", value:
"Nessus was able to login to the remote host using SSH or local
commands and extract the list of installed packages.");
  script_set_attribute(attribute:"solution", value:"n/a");
  script_set_attribute(attribute:"risk_factor",value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"2017/05/30");

  script_set_attribute(attribute:"plugin_type",value:"remote");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Misc.");

  script_copyright(english:"This script is Copyright (C) 2017-2026 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("find_service1.nasl", "ssh_settings.nasl", "clrtxt_proto_settings.nasl");
  script_dependencies("os_fingerprint_ssh_netconf.nasl", "ssh_check_compression.nasl", "satellite_settings.nbin");
  script_dependencies("vmware_installed_patches.nbin", "vmware_installed_vibs.nbin");
  script_dependencies("ibm_tem_get_packages.nbin", "ssh_rate_limiting.nasl", "vmware_vcenter_collect.nbin");
  script_dependencies("symantec_altiris_get_packages.nbin", "satellite_6_get_packages.nbin");

  script_timeout(20*60);
  exit(0);
}

include("datetime.inc");
include("string.inc");
include("byte_func.inc");

include("ssh_get_info2.inc");
include("ssh_func.inc");
include("ssh_lib.inc");

include("telnet_func.inc");
include("hostlevel_funcs.inc");
include("lcx.inc");

USE_SSH_WRAPPERS = TRUE;

start_time = gettimeofday();

# sleep for IOS-XR
sleep(1);
enable_ssh_wrappers();

use_hostlevel = FALSE;
var proto = NULL;
var port = NULL;
var user = NULL;

var timediff;

if (check_for_alternate_data_sources())
{
  security_note(port:0, extra:report);
  exit(0);
}

if(try_local_login())
{
  use_hostlevel = TRUE;
  proto = lcx::PROTO_LOCAL;
  report = '\nNessus can run commands on localhost to check if patches are applied.\n';
}
else
{
  var ssh_supplied, clrtxt_supplied;
  var disallowed_login, disallowed_login_error, disallowed_login_errors, error_list;
  # Check first to see if any credentials have been supplied
  if (
    !empty_or_null(get_kb_item("Secret/SSH/password")) ||
    !empty_or_null(get_kb_item("Secret/SSH/kdc_hostname")) ||
    !empty_or_null(get_kb_item("Secret/SSH/privatekey"))
  )
    ssh_supplied = TRUE;

  if (!empty_or_null(get_kb_item("Secret/ClearTextAuth/login")))
    clrtxt_supplied = TRUE;

  if (!ssh_supplied && !clrtxt_supplied)
    exit(0, "No SSH or cleartext credentials were supplied.");

  if(!empty_or_null(get_kb_item("SSH/disallowed_login_id")))
  {
    disallowed_login = TRUE;
    disallowed_login_error = NULL;
    disallowed_login_errors = get_kb_list(sshlib::SSH_LIB_KB_PREFIX + 'disallowed_login_id/error');
    if (!empty_or_null(disallowed_login_errors))
    {
      error_list = make_list(disallowed_login_errors);
      disallowed_login_error = '  - ' + join(error_list, sep:'\n  - ');
    }
  }

  var login_res = FALSE;
  var session;
  if (ssh_supplied)
  {
    # Remove any previous try_ssh_kb_settings_login() failure so login
    # will be tried again
    var prev_fail_kb = sshlib::SSH_LIB_KB_PREFIX + "try_ssh_kb_settings_login_failed";
    if (get_kb_item(prev_fail_kb))
    {
      dbg::detailed_log(
        lvl:2,
        src:SCRIPT_NAME,
        msg:"try_ssh_kb_settings_login() previously failed. Removing failure and trying again."
      );
      rm_kb_item(name:prev_fail_kb);
    }

    session = new("sshlib::session");
    login_res = sshlib::try_ssh_kb_settings_login(session:session, accept_none_auth:TRUE, force_none_auth:TRUE);

    # Report authentication attempts as an internal tag
    var reporter = new structured_data_authentication_status_information();
    sshlib::report_auth_try(reporter:reporter);
    delete reporter;

    sleep(1);
  }

  if(!login_res)
  {
    use_hostlevel = FALSE;
    if (clrtxt_supplied)
    {
      #    not implemented in hostlevel_funcs.inc
      #    login_method = "RLOGIN";
      #    use_hostlevel = try_rlogin();

      var login_method = "RSH";
      proto = lcx::PROTO_RSH;
      use_hostlevel = try_rsh_login();

      if(!use_hostlevel)
      {
        login_method = "REXEC";
        proto = lcx::PROTO_REXEC;
        use_hostlevel = try_rexec_login();
      }

      if(!use_hostlevel)
      {
        login_method = "TELNET";
        proto = lcx::PROTO_TELNET;
        use_hostlevel = try_telnet_login();
      }
    }

    var exit_message;
    if(!use_hostlevel && disallowed_login)
    {
      timediff = timeofday_diff(start:start_time, end:gettimeofday());
      exit_message = 'The host requested that login be performed as a different user:\n' + disallowed_login_error;

      lcx::log_issue(type:lcx::ISSUES_SVC, msg:exit_message, proto:lcx::PROTO_SSH, port:session.port);

      if(typeof(session) == 'object')
        session.close_connection();
      exit(1, exit_message + '\nRuntime : ' + timediff + ' seconds.');
    }
    else if(!use_hostlevel)
    {
      timediff = timeofday_diff(start:start_time, end:gettimeofday());
      if(typeof(session) == 'object')
      {
        port = session.port;
        session.close_connection();
      }
      exit_message = 'Unable to login to remote host with supplied credential sets.';
      var try_kb_login_errors = get_kb_list(sshlib::SSH_LIB_KB_PREFIX + "try_ssh_kb_settings_login/error");

      if (!empty_or_null(try_kb_login_errors))
      {
        error_list = make_list(try_kb_login_errors);
        exit_message += '\nErrors:\n  - ';
        exit_message += join(error_list, sep:'\n  - ');
      }

      if ("password" >< exit_message && "must be changed" >< exit_message)
        lcx::log_issue(type:lcx::ISSUES_ERROR, msg:exit_message, proto:lcx::PROTO_SSH, port:port);
      else
        lcx::log_issue(type:lcx::ISSUES_SVC, msg:exit_message, proto:lcx::PROTO_SSH, port:port);

      exit_message += '\nRuntime : ' + timediff + ' seconds.';
      exit(1, exit_message);
    }

    report = '\nIt was possible to log into the remote host via ' + login_method + '.\n';
    port = port_g;
    user = login;
    lcx::log_auth_success(proto:proto, port:port, user:user, clear_failures:TRUE);
  }
  else
  {
    # Gather / report session variables before closing session
    report = '\nIt was possible to log into the remote host via SSH using \''
             + session.login_method + '\' authentication.\n';

    rm_kb_item(name:"Host/Auth/SSH/" + session.port + "/Failure");
    report_xml_tag(tag:"ssh-auth-meth", value:session.login_method);

    proto = lcx::PROTO_SSH;
    port  = session.port;
    user  = session.user;

    host_info_key_val['remote_ssh_banner'] = session.remote_version;
    host_info_key_val['remote_ssh_userauth_banner'] = session.userauth_banner;
    host_info_key_val['kb_connection_id'] = session.get_kb_connection_id();

    var escl_method = get_kb_item(sshlib::SSH_LIB_KB_PREFIX + host_info_key_val['kb_connection_id'] + "/escalation_type");
    var cred_type = get_kb_item(sshlib::SSH_LIB_KB_PREFIX + host_info_key_val['kb_connection_id'] + "/cred_type");
    var auth_method = get_kb_item(sshlib::SSH_LIB_KB_PREFIX + host_info_key_val['kb_connection_id'] + "/login_method");

    session.close_connection();

    if(disallowed_login)
      report +=
        '\nNote, an attempt was made to log in with a different credential set in' +
        '\nthe policy but the host returned an error : ' +
        '\n' + strip(disallowed_login_error) + '\n';

    set_kb_item(name:'HostLevelChecks/proto', value:'ssh');
    report_xml_tag(tag:"local-checks-proto", value:"ssh");

    set_kb_item(name:"HostLevelChecks/login", value:user);
    report_xml_tag(tag:"ssh-login-used", value:user);

    if(!isnull(cred_type))
      replace_kb_item(name:"HostLevelChecks/cred_type", value:cred_type);
    if(!isnull(auth_method))
      replace_kb_item(name:"HostLevelChecks/auth_method", value:auth_method);

    sshlib::set_support_level(level: sshlib::SSH_LIB_SUPPORTS_LOGIN);

    dbg::detailed_log(src:SCRIPT_NAME, lvl:2, msg:'Login success! Associated escalation method to try: ' + escl_method);

    var exec_tried = FALSE;
    var ret;

    if(!escl_method || escl_method =~ "(?:Nothing|[Nn]one)")
    {
      dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'Trying exec checks.');

      ret = sshlib::try_ssh_exec(port:port, cmd_list:exec_checks);

      exec_tried = TRUE;
      if(ret[0])
      {
        dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'Exec checks successful. Using exec method to run commands.');
      }
      else
      {
        dbg::detailed_log(
          src:SCRIPT_NAME,
          lvl:1,
          msg:'The exec checks failed with the following error.',
          msg_details:{"Error":{"lvl":1, "value":ret[1]}});

        #Reset command values for devices that don't support exec
        var new_host_info_key_val = {};
        for(var key in host_info_key_val)
        {
          if("host_not" >!< key && "_unrecognized" >!< key && "_error" >!< key)
            new_host_info_key_val[key] = host_info_key_val[key];
        }

        host_info_key_val = new_host_info_key_val;
      }

    }
    if(sshlib::get_support_level() < sshlib::SSH_LIB_SUPPORTS_COMMANDS)
    {
      var report_backup1 = report;

      ret = sshlib::try_ssh_shell_handlers(port:port, shell_handlers:handler_list, cmd_list:shell_handler_checks);
      if(ret[0])
      {
        dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'Found working shell handler, using it to run commands.');

        if("command was successful without privilege escalation" >< ret[1])
        {
          var report_backup2 = report;
          report = report_backup1;

          var seperator = '\n';
          var additional_info = " an unknown reason. ";
          if(!isnull(ret[2]) && strlen(ret[2]) > 0)
          {
            additional_info = ' the following reason :\n\n' + ret[2] + '\n\n';
            seperator = " ";
          }

          dbg::detailed_log(src:SCRIPT_NAME, lvl:2, msg:'No escalation was used, trying exec checks in case one works.');
          ret = sshlib::try_ssh_exec(port:port, cmd_list:exec_checks);
          if(ret[0])
          {
            dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'Exec check successful, using it instead of the shell handler.');
            rm_kb_item(name:sshlib::SSH_LIB_KB_PREFIX + "shell_handler");
          }
          else
          {
            dbg::detailed_log(
              src:SCRIPT_NAME,
              lvl:2,
              msg:'No exec check worked, keeping the shell handler.',
              msg_details:{"Reason":{"lvl":2, "value":ret[1]}});
            report = report_backup2;
          }

          # Last use of escl_method in this plugin and only used for reporting, safe to modify.
          if (escl_method == "su_sudo")
            escl_method = "su+sudo";

          report += '\n' + "Note, though, that an attempt to elevate privileges using '" + escl_method + '\' failed\n' +
                    'for' + additional_info + 'Further commands will be run as the user' + seperator + 'specified in the scan policy.\n';
        }
        else
        {
          if(!isnull(escl_method))
            replace_kb_item(name:"HostLevelChecks/escl_method", value:escl_method);
        }
      }
      else
      {
        dbg::detailed_log(
          src:SCRIPT_NAME,
          lvl:1,
          msg:'The shell handler checks failed with the following error.',
          msg_details:{"Error":{"lvl":1, "value":ret[1]}});
      }
    }
    if(sshlib::get_support_level() < sshlib::SSH_LIB_SUPPORTS_COMMANDS && !exec_tried)
    {
      ret = sshlib::try_ssh_exec(port:port, cmd_list:exec_checks);
      exec_tried = TRUE;

      if(ret[0])
      {
        dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'Exec checks successful. Using exec method to run commands.');
        report += '\n' +
          "Note, though, that an attempt to elevate privileges using '" +
          escl_method + '\' failed\n' +
          'because a compatible shell handler was not found. Further commands\n' +
          'will be run as the user specified in the scan policy.\n';

        rm_kb_item(name:sshlib::SSH_LIB_KB_PREFIX + host_info_key_val['kb_connection_id'] + "/escalation_type");
      }
      else
      {
        dbg::detailed_log(
          src:SCRIPT_NAME,
          lvl:1,
          msg:'The exec checks failed with the following error.',
          msg_details:{"Error":{"lvl":1, "value":ret[1]}});
      }
    }
  }
}

if(typeof(session) == 'object') session.close_connection();

var local_checks_hostlevel = FALSE;
if(use_hostlevel)
{
  if(info_t == INFO_LOCAL)
    ret = try_hostlevel(cmd_list:local_scanner_checks);
  else
    ret = try_hostlevel(cmd_list:hostlevel_checks);

  if(ret[0])
  {
    if (get_kb_item("Host/local_checks_enabled"))
    {
      local_checks_hostlevel = TRUE;
      set_kb_item(name:sshlib::SSH_LIB_KB_PREFIX + "local_checks_hostlevel", value:TRUE);
    }
    dbg::detailed_log(
      src:SCRIPT_NAME,
      lvl:1,
      msg:'Found working shell handler: ' + get_kb_item(sshlib::SSH_LIB_KB_PREFIX + "/shell_handler") + '_shell_handler.');
  }
  else
  {
    dbg::detailed_log(src:SCRIPT_NAME, lvl:1, msg:'The host level checks failed to identify the host.');
  }
}

if(failure_kb_msg)
{
  if (!failure_kb_type)
    failure_kb_type = lcx::ISSUES_ERROR;
  lcx::log_issue(type:failure_kb_type, msg:failure_kb_msg, proto:proto, port:port, user:user);
}

if(sshlib::HOST_SUPPORT_LEVEL != sshlib::HOST_SUPPORTS_LOCAL_CHECKS && !local_checks_hostlevel)
{
  var failure_type = NULL;
  var failure_msg = NULL;
  switch (sshlib::HOST_SUPPORT_LEVEL)
  {
    case sshlib::HOST_LOCAL_CHECKS_UNAVAILABLE:
      set_kb_item(name:"HostLevelChecks/unavailable", value:SCRIPT_NAME);
      failure_msg =
        'We are able to identify the remote host.'+
        '\nOS security patch assessment is NOT supported.';
      report += '\n' + failure_msg + '\n';
      failure_type = lcx::ISSUES_INFO;
      break;
    case sshlib::HOST_LOCAL_CHECKS_ERROR:
      failure_msg =
        'We are able to identify the remote host, but encountered an error.'+
        '\nOS Security Patch Assessment is NOT available.';
      report += '\n' + failure_msg + '\n';
      failure_type = lcx::ISSUES_ERROR;
      break;
    case sshlib::HOST_SUPPORTS_COMMANDS:
      failure_msg =
        'We are able to run commands on the remote host, but are unable to'+
        '\ncurrently identify it in this plugin.';
      report += '\n' + failure_msg + '\n';
      failure_type = lcx::ISSUES_INFO;
      break;
    case sshlib::HOST_SUPPORTS_LOGIN:
      failure_msg =
        'The remote host is not currently supported by this plugin.';
      report += '\n' + failure_msg + '\n';
      failure_type = lcx::ISSUES_INFO;
      break;
    default:
      # should not be possible to get this far, but handle just in case
      failure_msg = 'Unable to run commands on the remote host.';
      report += '\n' + failure_msg + '\n';
      failure_type = lcx::ISSUES_INFO;
  }

  if(!failure_kb_msg && failure_msg)
    lcx::log_issue(type:failure_type, msg:failure_msg, proto:proto, port:port, user:user);
}

timediff = timeofday_diff(start:start_time, end:gettimeofday());
report += '\nRuntime : ' + timediff + ' seconds\n';
lcx::log_report(text:report);
security_note(port:0, extra:report);
exit(0);

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation