Lucene search

K
nessusThis script is Copyright (C) 2015-2024 and is owned by Tenable, Inc. or an Affiliate thereof.OS_FINGERPRINT2.NASL
HistoryMay 12, 2015 - 12:00 a.m.

Post-scan OS Identification

2015-05-1200:00:00
This script is Copyright (C) 2015-2024 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
80

7.1 High

AI Score

Confidence

Low

This plugin processes and reports on system information about the remote host detected by other plugins.
This information is used by Tenable products for informational and tracking purposes.

The main asset attributes processed in this plugin include:

  • OS
  • DNS Names
  • IP Address
  • MAC Addresses

In addition, this plugin generates additional OS fingerprinting data used by dashboards.

Note that this plugin does not produce output.

#TRUSTED 975b896f9e6119d8fcfe0f80896aae3e09537858a17c13c7575f357441c68cd4ecd809adaf781f32b11a34d98dba663873f511eb73b1c78f4a5389b0516e6658900d184b2b140e7aaab1a19ffce876ba45244c3d1a92bbf002c6891df64c12f3f3a5252d17689cc24e4e7bdf9e4ac727d9f94f0552f76d09f023ab1754a2819ade86f92eca8080e883962e2b11c94a5742e355d38665c170ee0b7c36af92b581f1fbd0de305316040e23cd437e653b30c378b541fc0043f5dfbdec47bccb50e3c2c3a0b1c40edf30601687d0330a0eff4dd3c1b94ce0b9b7e0589d5fd89ca47c3d5af22081b44312f2abdba2c63ac4761b0563d9bb164b41ea61d8bba9c8746b460fd59d8a4a9b8ac7fb3053414a09680e63ae59751b69c7c10285e5f90848af175f474f4dd5ae5325c5aa1d7e900ff5c335f77e3778827d7323a7f6faa791cf00ed61b342861ac9bc1e6b7e3606c577ba9510cb2960852446da7aab4d072ce492927c0376cfc1e2acbc353bcb5fc9a446e0e39f6a8e7ea642fbd0611a11be95bfa770f7aab0ea7a5780c35fd32f3cf7c959e4f01e4dad308860b650804d2da05ab7df0df96d80c69854eee4f64e45944378dbdd1df2a6accd8bcefab5bc9e37a4739ea8be7cf6183755ebe17c6e779da941be76dc9d775ced5889f08ceb99958ac8a439ad9283364c9402464e3b98b0268bc34892beff9b26063b73989f6ccd
#TRUST-RSA-SHA256 4e666d7903b2b77564e3843862002145203e3b0c7cc4fb32b3d93e67007acc9fd58208ecdbba013a0024ac10c1247c56de4b6e868c0355f4739e3885bd52856cbc87b18d57a39a196784eca0f343d43bf4259fd141e30c4228b9e2222d0b1bc32621f37696ff109d0b3240233becfa86e1ffc75070b576eca79bd9171b33bb85ed4bac6625e7745ada1b242826076eec743d24151d78707e800cfdbf0e4a9b34c1318f108e206daf364a18b59d5d9de269af9e5e1e39c607a11a89d98fa89e31b2d3da1b9a8213096a692172c8252d66d4e514b1838b0407e0c5c657582c33800f6341c31c17fae00ffcc8138c0ad643bd36cf66a2b10c4b353e36e29c2d95634102de159a7c317d9556fba60b1b7f25963155d7bd953d8bfe5f247352f5d7523845e0ec3f68ea62ac4be500f71c245dab21e7f3f550bdfd60a2daf0edf246d55486737e0fb69a8c1ee3730610b8da6317d1707fc6f74eeec1f9f9019b7f7731bb98b522e46266603b9211d059d67d71cfad487c6d07c5f2a0a09cb20f5dba35d0193f1c9ebc789dabadc5869e8302b9ef7cf66c175337eb37212351d2c9c8c61a7b1e1c138f8c068602b3d8ddaf4346e08199c28a4f469642f5d6563a1c3491acfe1299df4aa3990b25e4b566cefb8a9e0b87edb2e495d8abed77d63954e18189f3cc4ec5b1bb0e2c99eb78262bf9936e6dceffa14d2bef0889b0d3303f51ab
#%NASL_MIN_LEVEL 70300
#
# (C) Tenable Network Security, Inc.
#

include('deprecated_nasl_level.inc');
include("compat.inc");

if (description)
{
  script_id(83349);
  script_version("1.41");
  script_set_attribute(attribute:"plugin_modification_date", value:"2024/03/25");

  script_name(english:"Post-scan OS Identification");

  script_set_attribute(attribute:"synopsis", value:
"Processes and reports system information about the remote host.");
  script_set_attribute(attribute:"description", value:
"This plugin processes and reports on system information about the remote host detected by other plugins.
This information is used by Tenable products for informational and tracking purposes.

The main asset attributes processed in this plugin include:
  - OS
  - DNS Names
  - IP Address
  - MAC Addresses

In addition, this plugin generates additional OS fingerprinting data used by dashboards.

Note that this plugin does not produce output.");
  # https://docs.tenable.com/tenableio/Content/Explore/Assets/HostAssetDetails.htm
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?b7e0a415");
  script_set_attribute(attribute:"see_also", value:"https://docs.tenable.com/tenablesc/Content/ViewHostDetails.htm");
  script_set_attribute(attribute:"solution", value:"n/a");
  script_set_attribute(attribute:"risk_factor", value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"2015/05/12");

  script_set_attribute(attribute:"plugin_type", value:"combined");
  script_set_attribute(attribute:"agent", value:"all");
  script_set_attribute(attribute:"os_identification", value:"True");
  script_set_attribute(attribute:"always_run", value:TRUE);
  script_end_attributes();

  script_category(ACT_END);
  script_family(english:"General");

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

  exit(0);
}

include("agent.inc");
include("resolv_func.inc");
include("mac_address_func.inc");
include("json2.inc");
include("charset_func.inc");


function render_printable(string)
{
  var orig = string;
  string = get_ascii_printable(string:string);

  # Log any changes (should happen rarely)
  if (strlen(string) != strlen(orig))
    replace_kb_item(name:"Host/unprintable/" + string, value: 'unprintable characters found in original string');

  return string;
}

##
## Check for data populated by os_fingerprint* plugins
##
var output = '';
var best_score = -1;
var invalid_fqdn_count = 0;

# Dynamically makes fingerprint method list
# We only care about ones with Confidence
var methods = make_list();

var OS_kbs = get_kb_list("Host/OS/*/Confidence");
var matches, misc, kb, score, best_meth;

if ( !isnull(OS_kbs) )
{
  foreach var kb_name (keys(OS_kbs))
  {
    matches = pregmatch(pattern:"Host/OS/(\w+)/Confidence", string:kb_name);
    if (isnull(matches)) continue;
        
    # Avoid creating Windows tag on non-Windows assets
    misc = tolower(get_kb_item('Host/OS/Misc'));
    if (matches[1] == 'smb' && get_kb_item('SMB/not_windows'))  # Host/OS/smb
      continue;
    if (matches[1] == 'Misc' && misc =~ 'windows' && get_kb_item('SMB/not_windows'))  # Host/OS/Misc
      continue;
      
    methods = make_list(methods, matches[1]);
  }

  methods = list_uniq(methods);

  foreach var meth (methods)
  {
    kb = get_kb_item("Host/OS/" + meth);
    if( kb )
    {
      score = get_kb_item("Host/OS/" + meth + "/Confidence");
      if ( isnull(score) ) continue;
      if ( score < best_score ) continue;
      best_score = score;
      best_meth  = meth;
    }
  }
}
else
  best_meth = "Unknown";

# MAC addresses - consolidate and set "Host/mac_addrs" KB
get_all_macs();

# virtual MAC addresses - consolidate and set "Host/virtual_mac_addrs" KB
get_virtual_macs();

## Set tags from dashboard_report_host_get_tags
## /Host/Tags/report/
var tag_host_ip = "";
var tag_host_fqdn = "";
var tag_host_rdns = "";

##
#  Report FQDN info from all data sources
#
#  variable tag_host_fqdns to contain json-formatted 'ds' data structure of this info
##
var tag_host_fqdns = "";
var ds = make_list();
var add = make_list();

# add 'hostname -A' output data to FQDN tracking data structure
var tag_host_hostname_A = get_kb_item("Host/hostname-A");
var tag_host_note = get_kb_item("Host/hostname-A_note");
var invalid_key;

if (tag_host_hostname_A &&
    ("invalid" >!< tag_host_note ||
     "not attempted" >!< tag_host_note))
{
  tag_host_hostname_A = chomp(tag_host_hostname_A);
  var names = split(tag_host_hostname_A, sep:" ", keep:FALSE);
  names = list_uniq(names);

  foreach var name (names)
  {
    if (!empty_or_null(name))
    {
      if (valid_fqdn(fqdn:name))
      {
        add.FQDN = name;
        add.sources = [ "hostname-A" ];
        append_element(var:ds, value:add);
      }
      else
      {
        invalid_key = "invalid_FQDN_" + invalid_fqdn_count;
        set_kb_item(name:invalid_key, value:name);
        invalid_fqdn_count++;
      }
    }
  }
}

# add the name specified in scan configuration
var report_name, found;

report_name = get_kb_item("Flatline/get_host_report_name");
if (empty_or_null(report_name))
  report_name = get_host_report_name();

if (valid_fqdn(fqdn:report_name))
{
  foreach var ds_item (keys(ds))
  {
    if (ds[ds_item].FQDN == report_name)
    {
      found = TRUE;
      append_element(var:ds[ds_item].sources, value:"get_host_report_name()");
    }
  }
  if (!found)
  {
    add.FQDN = report_name;
    add.sources = [ "get_host_report_name()" ];
    append_element(var:ds, value:add);
  }
}
else
{
  invalid_key = "invalid_FQDN_" + invalid_fqdn_count;
  set_kb_item(name:invalid_key, value:report_name);
  invalid_fqdn_count++;
}

# add agent/non-agent identity-related data
var host_fqdn, legacy_val, rdns;
if (agent())
{
  if (!empty_or_null(agent_get_ip()))
    tag_host_ip = agent_get_ip();

  # FQDN
  host_fqdn = agent_fqdn();
  if (!empty_or_null(host_fqdn))
  {
    tag_host_fqdn = host_fqdn;

    # Create backup of previous value if overwriting
    legacy_val = get_kb_item("myHostName");
    if (!empty_or_null(legacy_val) && legacy_val != tag_host_fqdn)
      set_kb_item(name:"myHostName_previous", value:legacy_val);
    replace_kb_item(name:"myHostName", value:render_printable(string:tag_host_fqdn));

    # add agent data to FQDN tracking data structure
    found = FALSE;
    foreach ds_item (keys(ds))
    {
      if (ds[ds_item].FQDN == tag_host_fqdn)
      {
        found = TRUE;
        append_element(var:ds[ds_item].sources, value:"agent_fqdn()");
      }
    }
    if (!found)
    {
      add.FQDN = tag_host_fqdn;
      add.sources = [ "agent_fqdn()" ];
      append_element(var:ds, value:add);	
    }
  }
  else
  {
    invalid_key = "invalid_FQDN_" + invalid_fqdn_count;
    set_kb_item(name:invalid_key, value:tag_host_fqdn);
    invalid_fqdn_count++;
  }
}
else
{
  if (defined_func("get_host_ip") && get_host_ip() != NULL)
    tag_host_ip = get_host_ip();

  # rDNS lookup
  if (defined_func("get_host_fqdn"))
  {
    rdns = get_kb_item("Flatline/get_host_fqdn");
    if (empty_or_null(rdns))
      rdns = get_host_fqdn();

    if (!empty_or_null(rdns))
    {
      tag_host_rdns = rdns;

      # add rdns data to FQDN tracking data structure
      found = FALSE;
      foreach ds_item (keys(ds))
      {
        if (ds[ds_item].FQDN == tag_host_rdns)
        {
          found = TRUE;
          append_element(var:ds[ds_item].sources, value:"get_host_fqdn()");
        }
      }
      if (!found)
      {
        add.FQDN = tag_host_rdns;
        add.sources = [ "get_host_fqdn()" ];
        append_element(var:ds, value:add);	
      }
    }
  } 

  # FQDN - use user-specified FQDN instead of rDNS lookup otherwise use rDNS
  var fqdn = determine_fqdn();
  if (!empty_or_null(fqdn))
  {
    tag_host_fqdn = fqdn;

    # add user-specified data to FQDN tracking data structure
    found = FALSE;
    foreach ds_item (keys(ds))
    {
      if (ds[ds_item].FQDN == fqdn)
      {
        found = TRUE;
        append_element(var:ds[ds_item].sources, value:"determine_fqdn()");
      }
    }
    if (!found)
    {
      add.FQDN = fqdn;
      add.sources = [ "determine_fqdn()" ];
      append_element(var:ds, value:add);	
    }
  }
}

if (!empty_or_null(ds))
  tag_host_fqdns = json_write(ds);


##
#  Devnote: the following report_tags structure once contained lines
#    # report_xml_tag called by scan_info.nasl, no kb item set
#    #['Credentialed_Scan', "kb",     ""],
#  ...which have been removed
##


var report_tags =
[
  ['ssh-fingerprint',   "kb",     ["Host/OS/SSH/Fingerprint"]],
  ['mac-address',       "kb",     ["Host/mac_addrs"]],
  ['virtual-mac-address', "kb",     ["Host/virtual_mac_addrs"]],
  ['hostname',          "kb",     ["Host/hostname"]],
  ['host-fqdn',         "value",  tag_host_fqdn],
  ['host-fqdns',        "value",  tag_host_fqdns],
  ['host-rdns',         "value",  tag_host_rdns],
  ['host-ip',           "value",  tag_host_ip],
  ['smb-login-used',    "kb",     ["HostLevelChecks/smb_login"]],
  ['operating-system',  "kb",     ["Host/OS/" + best_meth]],
  ['operating-system-method',  "value", best_meth],
  ['operating-system-conf',    "value", string(best_score)]
];

var tag_value;
foreach var report_tag (report_tags)
{
  if (!get_kb_item("Host/Tags/report/" + report_tag[0]))
  {
    ## Retrieve tag value if it exists
    if (report_tag[1] == "kb")
    {
      foreach var tag_kb_item (report_tag[2])
      {
        tag_value = get_kb_item(tag_kb_item);
        if (strlen(tag_value))
          break;
      }
    }
    else if (report_tag[1] == "value")
    {
      tag_value = report_tag[2];
    }
    # Perform any manual processing required on specific tags here.
    if (report_tag[0] == "operating-system")
    {
      # At least for now, replace the legacy macOS formatting with the current expected format
      # All sw_vers response appear as Mac OS X for 10.* and macOS for 11.* onward.
      # Consult RES-101983 for further details.
      if (preg(pattern:"^Mac OS X ", string:tag_value))
      {
        if (!preg(pattern:"^Mac OS X 10\.", string:tag_value))
        {
          tag_value = ereg_replace(string:tag_value, pattern:"^Mac OS X ", replace:"macOS ");
        }
        # KB for flatline testing purposes
        replace_kb_item(name:"Flatline/MacOSX/operating-system/os_fingerprint2", value:tag_value);
      }
    }

    ## Set Host/Tags/report/* value
    if (strlen(tag_value))
    {
      if ( "hostname" >< report_tag[0] ||
           "host-fqdns" >< report_tag[0] ||
           "host-rdns" >< report_tag[0] )
      {
        tag_value = render_printable(string:tag_value);
      }

      replace_kb_item(name: "Host/Tags/report/" + report_tag[0], value: tag_value);
      report_xml_tag(tag:report_tag[0], value:tag_value);
    }
  }
}

## Set additional tags not in dashboard_report_host_get_tags
var os_full = get_kb_item("Host/OS/" + best_meth);
var tag_os = 'other';
var tag_vendor = '';
var tag_product = '';
var tag_cpe = '';
var os_linux, os_windows, os_mac, kb_exists, kb_val_match;
if (strlen(os_full) && preg(pattern:"windows|microsoft", string: os_full, icase:TRUE)) {
  tag_os = 'windows';
  tag_vendor = 'microsoft';
  tag_product = 'windows';
  tag_cpe = build_cpe_from_tags(type:'o', vendor:tag_vendor, product:tag_product);
}
else if (strlen(os_full) && preg(pattern:"linux|unix", string: os_full, icase:TRUE)) {
  tag_os = 'linux';
  tag_vendor = 'linux';
  tag_product = 'linux_kernel';
  tag_cpe = build_cpe_from_tags(type:'o', vendor:tag_vendor, product:tag_product);
}
else if (strlen(os_full) && preg(pattern: "apple|mac|os_x|osx|os x|iphone|ipad", string: os_full, icase: TRUE)) {
  tag_os = 'mac';
  tag_vendor = 'apple';
  tag_product = '';
  tag_cpe = build_cpe_from_tags(type:'o', vendor:tag_vendor, product:tag_product);
}
else
{
  # Generic OS + CPE Vendor/Product pairs
  # os_*[0]         os_*[1], os_*[2]
  os_linux =    ["linux",   "linux",      "linux_kernel"];
  os_windows =  ["windows", "microsoft",  "windows"];
  os_mac =      ["mac",     "apple",      "mac_os"];
  #os_mac_osx = ["mac", "apple", "mac_os_x"];
  #os_mac_server = ["mac", "apple", "mac_os_server"];
  #os_mac_x_server = ["mac", "apple", "mac_os_x_server"];
  #os_iphone = ["mac", "apple", "iphone_os"];

  kb_exists = [
    [os_linux, "Host/Linux/Distribution"]
  ];
  kb_val_match = [
    [os_linux, "LINUX", "mDNS/os"],
    [os_linux, "Linux", "Host/OS/uname"],
    [os_linux, "Archos70", "upnp/modelName"],
    [os_linux, "linux|solaris", "Services/data_protector/patch_info_is_str"],
    [os_linux, "linux|unix|Sun SNMP|hp-ux|hpux", "SNMP/sysName"],
    [os_linux, "openBSD|linux|unix|netbsd|aix|hp-ux|sco_sv", "Host/OS/ntp"],
    [os_linux, "linux|unix|Nexus [0-9]+[a-zA-Z]* Switch|Data Domain OS", "SSH/textbanner/*"],
    [os_linux, "linux|unix|netbsd|openbsd|freebsd|minix|sunos|aix|irix|dragonfly", "Host/uname"],
    [os_linux, "linux|unix|sun_ssh|freebsd|netbsd|ubuntu|debian|cisco|force10networks", "SSH/banner/*"],
    [os_linux, "linux|unix|iris|aix|minix|netbsd|openbsd|freebsd|Dell Force10|cisco|Silver Peak Systems|HP-UX|hpux", "SNMP/sysDesc"],

    [os_windows, "Service Pack ", "SMB/CSDVersion"],
    [os_windows, "Windows", "Host/OS/smb"],
    [os_windows, "Windows", "Host/Veritas/BackupExecAgent/OS_Version"],
    [os_windows, "Windows ", "SMB/ProductName"],
    [os_windows, "Windows ", "upnp/modelName"],
    [os_windows, "microsoft", "Services/data_protector/patch_info_is_str"],
    [os_windows, "microsoft|windows", "SNMP/sysName"],
    [os_windows, "microsoft|windows", "Host/OS/ntp"],

    [os_mac, "AFP[X23]", "Host/OS/AFP/fingerprint"],
    [os_mac, "apple|darwin", "SNMP/sysDesc"],
    [os_mac, "darwin", "Host/uname"],
    [os_mac, "Mac OS X", "mDNS/os"],
    [os_mac, "cygwin|mingw32", "Host/uname"],
    [os_mac, "Darwin Kernel Release", "SNMP/sysName"],
    [os_mac, "(Darwin).*(x86_64|i386)", "Host/OS/ntp"]
  ];

  var kblist, os_info, kbval, addl_tags;
  foreach var kbitem (kb_exists)
  {
    if (get_kb_item(kbitem[1]))
    {
      os_info = kbitem[0];
      tag_os = os_info[0];
      tag_vendor = os_info[1];
      tag_product = os_info[2];
      tag_cpe = build_cpe_from_tags(type:'o', vendor:tag_vendor, product:tag_product);
      break;
    }
  }

  foreach kbitem (kb_val_match)
  {
    if (tag_cpe != '') break;
    kblist = get_kb_list(kbitem[2]);
    foreach var kbkey (keys(kblist))
    {
      kbval = kblist[kbkey];
      if (preg(pattern: kbitem[1], string: kbval, icase: TRUE))
      {
        os_info = kbitem[0];
        tag_os = os_info[0];
        tag_vendor = os_info[1];
        tag_product = os_info[2];
        tag_cpe = build_cpe_from_tags(type:'o', vendor:tag_vendor, product:tag_product);
        break;
      }
    }
  }
}


##
#  Devnote, the following addl_tags structure once held the following commented items:
#    #['id',            "value",  ""],
#    #['is_new',        "value",  ""],
#    #['is_auth',       "value",  ""],
#    #['scan_type',     "value",  ""],
#    #['severity',      "value",  ""],
#    #['severitycount', "value",  ""],
#    #['last_update',   "value",  ""],
#    #['host_index',    "value",  ""]
##
addl_tags =
[
  ['os',            "value",  tag_os],
  ['cpe',           "value",  tag_cpe]
];

foreach var addl_tag (addl_tags)
{
  if (!get_kb_item("Host/Tags/report/" + addl_tag[0]))
  {
    ## Retrieve tag value if it exists
    if (addl_tag[1] == "kb")
    {
      foreach tag_kb_item (addl_tag[2])
      {
        tag_value = get_kb_item(tag_kb_item);
        if (strlen(tag_value))
          break;
      }
    }
    else if (addl_tag[1] == "value")
    {
      tag_value = addl_tag[2];
    }

    ## Set Host/Tags/report/* value
    if (strlen(tag_value))
    {
      set_kb_item(name: "Host/Tags/" + addl_tag[0], value: tag_value);
      report_xml_tag(tag:addl_tag[0], value:tag_value);
    }
  }
}

function build_cpe_from_tags(type, vendor, product)
{
  local_var cpe_string;
  cpe_string = 'cpe:/';
  if (type != '')
  {
    cpe_string += type;
    if (vendor != '')
    {
      cpe_string += ':'+vendor;
      if (product != '')
      {
        cpe_string += ':'+product;
      }
    }
  }
  return cpe_string;
}

7.1 High

AI Score

Confidence

Low