Lucene search
+L

Google Chrome Detection (Windows)

🗓️ 12 Sep 2008 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 102 Views

Google Chrome is installed on the remote Windows hos

Refs
Code
SourceLink
googlewww.google.com/chrome/
#
#  (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(34196);
  script_version("1.27");
  script_set_attribute(attribute:"plugin_modification_date", value:"2025/07/10");
  script_xref(name:"IAVT", value:"0001-T-0511");

  script_name(english:"Google Chrome Detection (Windows)");

  script_set_attribute(attribute:"synopsis", value:
"The remote Windows host contains a web browser.");
  script_set_attribute(attribute:"description", value:
"Google Chrome, a web browser from Google, is installed on the remote
Windows host.");
  script_set_attribute(attribute:"see_also", value:"https://www.google.com/chrome/");
  script_set_attribute(attribute:"solution", value:
"n/a");
  script_set_attribute(attribute:"agent", value:"windows");
  script_set_attribute(attribute:"risk_factor", value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"2008/09/12");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"asset_inventory", value:"True");
  script_set_attribute(attribute:"asset_inventory_category", value:"software_enumeration");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:google:chrome");
  script_set_attribute(attribute:"thorough_tests", value:"true");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Windows");

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

  script_dependencies("smb_hotfixes.nasl");
  script_require_keys("SMB/Registry/Enumerated");
  script_require_ports(139, 445);

  exit(0);
}

include("smb_func.inc");
include("install_func.inc");
include("collection_metadata.inc");

var app = "Google Chrome";
var fa_app_name = "chrome";

# Walk up the path and check if each directory
# in the path is a reparse point.
function reparse_points_exist_in_path(check_path)
{
  local_var check_ret;

  while (check_path != "\" && strlen(check_path) > 0)
  {
    check_ret = FindFirstFile(pattern:check_path);

    # Look for reparse point directories
    # in file attributes.
    if (!isnull(check_ret[2]) &&
      # FILE_ATTRIBUTE_DIRECTORY
      ((check_ret[2] >> 4) & 0x1) &&
      # FILE_ATTRIBUTE_REPARSE_POINT
      ((check_ret[2] >> 10) & 0x1)
    )
      return TRUE;

    check_path = ereg_replace(
      pattern:"^(.*)\\([^\\]*)?$",
      replace:"\1",
      string:check_path
    );
  }
  return FALSE;
}


get_kb_item_or_exit("SMB/Registry/Enumerated");

# Connect to the appropriate share.
var name    =  kb_smb_name();
var port    =  kb_smb_transport();
#if (!get_port_state(port)) audit(AUDIT_PORT_CLOSED, port);
var login   =  kb_smb_login();
var pass    =  kb_smb_password();
var domain  =  kb_smb_domain();

#soc = open_sock_tcp(port);
#if (!soc) audit(AUDIT_SOCK_FAIL, port);

#session_init(socket:soc, hostname:name);
if(!smb_session_init()) audit(AUDIT_FN_FAIL, 'smb_session_init');

var rc = NetUseAdd(login:login, password:pass, domain:domain, share:"IPC$");
if (rc != 1) {
  NetUseDel();
  audit(AUDIT_SHARE_FAIL, "IPC$");
}


# Connect to remote registry.
var hklm = RegConnectRegistry(hkey:HKEY_LOCAL_MACHINE);
if (isnull(hklm))
{
  NetUseDel();
  audit(AUDIT_REG_FAIL);
}


# Determine possible paths where it might be installed.
var paths = make_array();
var path_keys = make_array();
var keys = make_list(
  "SOFTWARE\Classes\Applications\chrome.exe\shell\open\command",
  "SOFTWARE\Classes\ChromeHTML\shell\open\command",
  "SOFTWARE\Clients\StartMenuInternet\chrome.exe\shell\open\command",
  "SOFTWARE\Clients\StartMenuInternet\Google Chrome\shell\open\command"
);

var path = NULL;
var key_h, item, exe, lcpath;

foreach var key (keys)
{
  key_h = RegOpenKey(handle:hklm, key:key, mode:MAXIMUM_ALLOWED);
  if (!isnull(key_h))
  {
    item = RegQueryValue(handle:key_h, item:NULL);
    if (!isnull(item))
    {
      # nb: the exe itself appears in quotes.
      exe = ereg_replace(pattern:'^"([^"]+)".*', replace:"\1", string:item[1]);
      path = ereg_replace(pattern:'^(.+)\\\\[^\\\\]+\\.exe.*$', replace:"\1", string:exe, icase:TRUE);
      lcpath = tolower(path);
      if (!paths[lcpath])
      {
          paths[lcpath] = path;
          path_keys[path] = key;
      }
    }
    RegCloseKey(handle:key_h);
  }
}

# If the "Perform thorough tests" setting is enabled, include local user directories too.
var pdir = "";
var winroot;

if (thorough_tests)
{
  # Find out where user directories are stored.

  key = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList";
  key_h = RegOpenKey(handle:hklm, key:key, mode:MAXIMUM_ALLOWED);
  if (!isnull(key_h))
  {
    item = RegQueryValue(handle:key_h, item:"ProfilesDirectory");
    if (!isnull(item)) pdir = item[1];

    RegCloseKey(handle:key_h);
  }

  if (pdir && stridx(tolower(pdir), "%systemdrive%") == 0)
  {
    key = "SOFTWARE\Microsoft\Windows NT\CurrentVersion";
    key_h = RegOpenKey(handle:hklm, key:key, mode:MAXIMUM_ALLOWED);
    if (!isnull(key_h))
    {
      item = RegQueryValue(handle:key_h, item:"SystemRoot");
      if (!isnull(item))
      {
        winroot = ereg_replace(pattern:"^([A-Za-z]):.*", replace:"\1:", string:item[1]);
        pdir = winroot + substr(pdir, strlen("%systemdrive%"));
      }

      RegCloseKey(handle:key_h);
    }
  }
}
RegCloseKey(handle:hklm);
NetUseDel(close:FALSE);

if (pdir)
{
  # Get OS ver
  var windows_version = get_kb_item("SMB/WindowsVersion");

  var share = ereg_replace(pattern:"^([A-Za-z]):.*", replace:"\1$", string:pdir);
  var dirpat = ereg_replace(pattern:"^[A-Za-z]:(.*)", replace:"\1\*", string:pdir);

  rc = NetUseAdd(login:login, password:pass, domain:domain, share:share);
  if (rc == 1)
  {
    var retx = FindFirstFile(pattern:dirpat);
    var user;
    while (!isnull(retx[1]))
    {
      path = NULL;
      user = retx[1];
      if (user != "." && user != "..")
      {
        # 2k / 2k3 / XP
        if (windows_version < 6 )
          path = pdir + "\" + user + "\Local Settings\Application Data\Google\Chrome\Application";
        # Vista / Win 7 / 2k8
        else
          path = pdir + "\" + user + "\AppData\Local\Google\Chrome\Application";

        if (!isnull(path))
        {
          lcpath = tolower(path);
          if (!paths[lcpath]) paths[lcpath] = path;
        }
      }
      retx = FindNextFile(handle:retx);
    }
  }
}

# Determine version numbers of any actual Chrome installs.
var vers = make_array();


##
#  Check both 'Program Files (x86)' and 'Program Files'
#  Use uppercase path keys to ensure uniqueness
##
var altpath, up_altpath, altpaths, path_ds, up_path;
foreach path (paths)
{
  up_path = toupper(path);
  path_ds[up_path].display_path = path;
  path_ds[up_path].registry_key = path_keys[path];
  if ("Program Files (x86)" >< path)
  {
    altpath = path - " (x86)";
    up_altpath = toupper(altpath);
    altpaths[up_altpath].display_path = altpath;
    altpaths[up_altpath].registry_key = path_keys[altpath];
  }
  else if ("Program Files" >< path)
  {
    altpath = ereg_replace(string:path, pattern:"Program Files", replace:"Program Files (x86)");
    up_altpath = toupper(altpath);
    altpaths[up_altpath].display_path = altpath;
    altpaths[up_altpath].registry_key = path_keys[altpath];
  }
}
foreach altpath (keys(altpaths))
{
  path_ds[altpath].display_path = altpaths[altpath].display_path;
  path_ds[altpath].registry_key = altpaths[altpath].registry_key;
}


spad_log(message:'path datastructure: ' + obj_rep(path_ds));

var reg_key, strip_path, version;
var max_version, max_dll, size, modified, max_size, max_modified, tmp;
##
#  Check paths
##
foreach var path_key (keys(path_ds))
{
  path = path_ds[path_key].display_path;
  reg_key = path_ds[path_key].registry_key;
  share = ereg_replace(pattern:"^([A-Za-z]):.*", replace:"\1$", string:path);
  dirpat = ereg_replace(pattern:"^[A-Za-z]:(.*)", replace:"\1\*", string:path);
  NetUseDel(close:FALSE);

  rc = NetUseAdd(login:login, password:pass, domain:domain, share:share);
  if (rc == 1)
  {

    # Look for, and skip, Windows Reparse Points
    # that would cause one install to be reported
    # twice.
    strip_path = dirpat - "\*";
    if (reparse_points_exist_in_path(check_path:strip_path))
      continue;

    max_version = "";
    retx = FindFirstFile(pattern:dirpat);

    var dir, fh, dll, ver, i, max;
    while (!isnull(retx[1]))
    {
      dir = retx[1];
      if (dir =~ "^[0-9]+[0-9.]+$")
      {
        dll = substr(dirpat, 0, strlen(dirpat)-2-1) + "\" + dir + "\chrome.dll";
        fh = CreateFile(
          file:dll,
          desired_access:GENERIC_READ,
          file_attributes:FILE_ATTRIBUTE_NORMAL,
          share_mode:FILE_SHARE_READ,
          create_disposition:OPEN_EXISTING
        );
        if (!isnull(fh))
        {
          ver = GetFileVersion(handle:fh);
          if (!isnull(ver))
          {
            size = direct_GetFileSize(handle:fh);
            tmp = GetFileVersionEx(handle:fh);
            if (!isnull(tmp) && !isnull(tmp['dwTimeDateStamp']))
            {
                modified = tmp['dwTimeDateStamp'];
            }
            version = ver[0] +  "." +  ver[1] +  "." +  ver[2] +  "." +  ver[3];
            # nb: upgrades don't remove old versions so we look for the highest.
            if (!max_version)
            {
              max_version = version;
              max_dll = dll;
              max_size = size;
              max_modified = modified;
            }
            else
            {
              max = split(max_version, sep:'.', keep:FALSE);
              for (i=0; i<4; i++)
                max[i] = int(max[i]);

              if (
                ver[0] > max[0] ||
                (ver[0] == max[0] && ver[1] > max[1]) ||
                (ver[0] == max[0] && ver[1] == max[1] && ver[2] > max[2]) ||
                (ver[0] == max[0] && ver[1] == max[1] && ver[2] == max[2] && ver[3] > max[3])
              )
              {
                max_version = version;
                max_dll = dll;
                max_size = size;
                max_modified = modified;
              }
            }
          }
          CloseFile(handle:fh);
        }
      }
      retx = FindNextFile(handle:retx);
    }

    if (max_version)
    {
      var file_info = { dll: max_dll, size: max_size, modified: max_modified };
      if (!empty_or_null(vers[max_version]))
      {
          append_element(value: path, var: vers[max_version].paths);
          append_element(value: reg_key, var: vers[max_version].keys);
          append_element(value: file_info, var: vers[max_version].version_file_info);
      }
      else
      {
          vers[max_version] = {
              paths: [path],
              version_file_info: [file_info],
              keys: [reg_key]
          };
      }
    }
  }
}
NetUseDel();


# If any installs were found, mark it as installed in the KB and issue a report.
if (max_index(keys(vers)))
{
  set_kb_item(name:"SMB/Google_Chrome/Installed", value:TRUE);

  var info = "";
  foreach version (sort(keys(vers)))
  {
    var len = max_index(vers[version].paths);
    for(var idx = 0; idx < len; idx++)
    {
      path = vers[version].paths[idx];
      file_info = vers[version].version_file_info[idx];
      reg_key = vers[version].keys[idx];
      set_kb_item(name:"SMB/Google_Chrome/"+version+"/"+path, value:path);
      var collect = new collection_metadata::collection_metadata();
      collect.track_windows_pe_version(
          path: file_info.dll,
          size: file_info.size,
          last_modified: file_info.modified
      );

      register_install(
        app_name:app,
        vendor : 'Google',
        product : 'Chrome',
        path:path,
        version:version,
        cpe:"cpe:/a:google:chrome",
        fa_app_name: fa_app_name,
        enhanced_inventory: collect.inventory_data());

      delete(collect);
    }
  }

  if (!thorough_tests)
  {
    # nb: report already has an extra blank line at the end.
    info +=
      'Note that Nessus only looked in the registry for evidence of Google\n' +
      'Chrome. If there are multiple users on this host, you may wish to\n' +
      "enable the 'Perform thorough tests' setting and re-scan. This will" + '\n' +
      "cause Nessus to scan each local user's directory for installs." + '\n';
  }

  report_installs(app_name:app, port:port, extra:info);
}
else
{
  audit(AUDIT_NOT_INST, app);
}

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

10 Jul 2025 00:00Current
5.4Medium risk
Vulners AI Score5.4
102