Adobe Acrobat Detection
| Source | Link |
|---|---|
| acrobat | www.acrobat.adobe.com/us/en/acrobat.html |
#%NASL_MIN_LEVEL 80900
##
# (C) Tenable, Inc.
##
include('compat.inc');
if (description)
{
script_id(40797);
script_version("1.38");
script_set_attribute(attribute:"plugin_modification_date", value:"2026/08/17");
script_xref(name:"IAVT", value:"0001-T-0512");
script_name(english:"Adobe Acrobat Detection");
script_set_attribute(attribute:"synopsis", value:
"Adobe Acrobat is installed on the remote Windows host.");
script_set_attribute(attribute:"description", value:
"Adobe Acrobat, a PDF file creation and editing tool, is installed on
the remote Windows host.");
script_set_attribute(attribute:"see_also", value:"https://acrobat.adobe.com/us/en/acrobat.html");
script_set_attribute(attribute:"solution", value:"n/a");
script_set_attribute(attribute:"risk_factor", value:"None");
script_set_attribute(attribute:"plugin_publication_date", value:"2009/08/28");
script_set_attribute(attribute:"plugin_type", value:"local");
script_set_attribute(attribute:"cpe", value:"cpe:/a:adobe:acrobat");
script_set_attribute(attribute:"asset_inventory", value:"True");
script_set_attribute(attribute:"asset_inventory_category", value:"software_enumeration");
script_set_attribute(attribute:"agent", value:"windows");
script_end_attributes();
script_category(ACT_GATHER_INFO);
script_family(english:"Windows");
script_copyright(english:"This script is Copyright (C) 2009-2026 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('install_func.inc');
include('local_detection_win.inc');
include("universal_collection.inc");
get_kb_item_or_exit('SMB/Registry/Enumerated');
# Per-path registry metadata populated in collect(), consumed in main flow.
var _path_min = make_array();
var _path_max = make_array();
var _path_su1 = make_array();
# @collection-signature
var signature = {
'Windows': {
'UninstalledRegistry': [
{
'Signature': [
{ 'Name': { 'Regex': 'Adobe Acrobat(?! Reader| Plugin)' } }
]
}
],
'Files': [
{
'Signature': [
{ 'FilePath': { 'EndsWith': '\\Acrobat\\Acrobat.exe' } }
],
'Get': {
'PEVersion': [
{ 'Value': 'ProductVersionString', 'Label': 'Acrobat.exe ProductVersionString' }
]
}
}
]
}
};
function collect()
{
var collector = new universal_collection::collector();
var uninst_sig_field, uninst_sig_operator, uninst_pattern;
var file_sig_field, file_sig_operator, file_endswith, pev_block;
# --- Phase 1: Uninstall registry discovery (signature-driven) ---
uninst_sig_field = 'Name';
uninst_sig_operator = 'Regex';
uninst_pattern = NULL;
foreach var uninst_entry (signature['Windows']['UninstalledRegistry'])
{
foreach var uninst_criteria (uninst_entry['Signature'])
{
uninst_pattern = uninst_criteria[uninst_sig_field][uninst_sig_operator];
if (!isnull(uninst_pattern)) break;
}
if (!isnull(uninst_pattern)) break;
}
if (!isnull(uninst_pattern))
{
local_detection_win::registry::collect_uninstall_matches(
collector:collector, display_name_pattern:uninst_pattern);
}
# --- Phase 2: Registry walk SOFTWARE\Adobe\Adobe Acrobat\* ---
registry_init();
var hklm = registry_hive_connect(hive:HKEY_LOCAL_MACHINE, exit_on_fail:TRUE);
var base_key = "SOFTWARE\\Adobe\\Adobe Acrobat";
var subkeys = get_registry_subkeys(handle:hklm, key:base_key);
var key2, path, min, max, su1;
foreach var subkey (subkeys)
{
if (!strlen(subkey) || (subkey !~ "^[0-9.]+$" && subkey != "DC"))
continue;
path = NULL;
min = NULL;
max = NULL;
su1 = NULL;
if (subkey !~ "^20\\d\\d$" && subkey != "DC")
key2 = base_key + "\\" + subkey + "\\Installer";
else
key2 = base_key + "\\" + subkey + "\\InstallPath";
var vmax = get_registry_value(handle:hklm, item:key2 + "\\VersionMax");
if (!isnull(vmax)) max = int(vmax);
var vmin = get_registry_value(handle:hklm, item:key2 + "\\VersionMin");
if (!isnull(vmin)) min = int(vmin);
var path_val = get_registry_value(handle:hklm, item:key2 + "\\Path");
if (!isnull(path_val))
{
path = path_val;
if (strlen(path) > 0 && path[strlen(path)-1] == "\")
path = substr(path, 0, strlen(path)-2);
}
if (subkey =~ "^20\\d\\d$" || subkey == "DC")
{
var installer_key = base_key + "\\" + subkey + "\\Installer";
var sca_level = get_registry_value(handle:hklm, item:installer_key + "\\SCAPackageLevel");
if (!isnull(sca_level) && int(sca_level) == 1)
{
dbg::detailed_log(lvl:1, msg:'Installed product is Acrobat Reader (SCAPackageLevel=1), skipping subkey: ' + subkey);
continue;
}
var default_val = get_registry_value(handle:hklm, item:key2 + "\\");
if (!isnull(default_val) && strlen(default_val) > 8 &&
default_val[strlen(default_val)-8] == '\\' &&
tolower(substr(default_val, strlen(default_val)-7)) == 'acrobat')
path = substr(default_val, 0, strlen(default_val)-9);
else if (!isnull(default_val))
path = default_val;
}
if (subkey == '8.0' && !isnull(min) && (min >> 16 == 2))
{
var su1_val = get_registry_value(handle:hklm, item:key2 + "\\VersionSU");
if (!isnull(su1_val)) su1 = su1_val;
}
if (!empty_or_null(path))
{
if (strlen(path) > 0 && path[strlen(path)-1] == "\")
path = substr(path, 0, strlen(path)-2);
_path_min[tolower(path)] = min;
_path_max[tolower(path)] = max;
_path_su1[tolower(path)] = su1;
dbg::detailed_log(lvl:1, msg:'Found Adobe Acrobat in registry walk: ' + path);
}
}
RegCloseKey(handle:hklm);
# Merge registry-walk paths with uninstall-discovered paths
var existing_paths = collector.paths();
foreach var rp (keys(_path_min))
{
var already = FALSE;
var ep;
foreach ep (existing_paths)
{
if (tolower(rp) == tolower(ep)) { already = TRUE; break; }
}
if (!already)
append_element(var:existing_paths, value:rp);
}
if (!thorough_tests && empty_or_null(existing_paths))
{
close_registry();
return collector;
}
close_registry(close:FALSE);
# --- Read file signature metadata ---
file_sig_field = 'FilePath';
file_sig_operator = 'EndsWith';
file_endswith = NULL;
pev_block = NULL;
foreach var file_entry (signature['Windows']['Files'])
{
foreach var file_criteria (file_entry['Signature'])
{
file_endswith = file_criteria[file_sig_field][file_sig_operator];
if (!isnull(file_endswith)) break;
}
pev_block = file_entry['Get']['PEVersion'];
if (!isnull(file_endswith)) break;
}
# --- Phase 3: File version checks ---
var exe_path, ver, err, version, dll, dll_ver, dll_err;
var md_entries, pev_entry;
foreach path (existing_paths)
{
# Normalize trailing backslash
if (strlen(path) > 0 && path[strlen(path)-1] == "\")
path = substr(path, 0, strlen(path)-2);
exe_path = hotfix_append_path(path:path, value:file_endswith);
if (!hotfix_file_exists(path:exe_path))
{
dbg::detailed_log(lvl:1, msg:'Acrobat.exe not found: ' + exe_path);
continue;
}
ver = hotfix_get_pversion(path:exe_path);
err = hotfix_handle_error(error_code:ver['error'], file:exe_path);
if (err && ver['error'] != HCF_NOVER)
{
dbg::detailed_log(lvl:1, msg:err);
continue;
}
version = ver['version'];
# v7.0.8: Acrobat.exe reports 7.1.0 â use acrodist.exe
if (!empty_or_null(version) && version =~ "^7\.0\.8\.")
{
dll = hotfix_append_path(path:hotfix_append_path(path:path, value:'Distillr'), value:'acrodist.exe');
if (hotfix_file_exists(path:dll))
{
dll_ver = hotfix_get_pversion(path:dll);
dll_err = hotfix_handle_error(error_code:dll_ver['error'], file:dll);
if (!dll_err || dll_ver['error'] == HCF_NOVER)
version = dll_ver['version'];
}
}
# v11.0.04: Acrobat.exe does not update â use Acrobat.dll
else if (!empty_or_null(version) && version =~ "^11\.0\.04\.")
{
dll = hotfix_append_path(path:hotfix_append_path(path:path, value:'Acrobat'), value:'Acrobat.dll');
if (hotfix_file_exists(path:dll))
{
dll_ver = hotfix_get_pversion(path:dll);
dll_err = hotfix_handle_error(error_code:dll_ver['error'], file:dll);
if (!dll_err || dll_ver['error'] == HCF_NOVER)
version = dll_ver['version'];
}
}
md_entries = make_list();
if (!empty_or_null(pev_block))
{
foreach pev_entry (pev_block)
{
if (pev_entry['Value'] != 'ProductVersionString') continue;
append_element(var:md_entries, value:collector.make_peversion_match_data_entry(
value : version,
label : pev_entry['Label'],
peversion_type : 'ProductVersionString'
));
}
}
collector.add_file_match(
filepath : exe_path,
sig_field : file_sig_field,
sig_operator : file_sig_operator,
sig_val : file_endswith,
match_data : md_entries
);
}
hotfix_check_fversion_end();
return collector;
}
##
# Main
##
var app = 'Adobe Acrobat';
var cpe = 'cpe:/a:adobe:acrobat';
var vendor = 'Adobe';
var collector = get_collector_or_collect(signature:signature, collect_func:@collect);
var uninstall_matches = collector.get_matches_by_source(source:'UninstalledRegistry');
var file_matches = collector.get_matches_by_source(source:'Files');
if (empty_or_null(file_matches))
{
if (!empty_or_null(uninstall_matches))
audit(AUDIT_UNINST, app);
else
audit(AUDIT_NOT_INST, app);
}
# Derive file sig field from signature for path stripping
var _file_sig_field = 'FilePath';
var _file_sig_op = 'EndsWith';
var _pev_label = NULL;
foreach var _fsig (signature['Windows']['Files'])
{
foreach var _fcrit (_fsig['Signature'])
{
foreach var _ff (keys(_fcrit))
{
_file_sig_field = _ff;
break;
}
break;
}
foreach var _pev (_fsig['Get']['PEVersion'])
{
_pev_label = _pev['Label'];
break;
}
break;
}
var finding, install_path, file_version, version, regversion, match_data;
var min_val, max_val, su1_val, vparts, a, b, c, d, i, version_ui, track;
var extra, extra_nr, pat, vm;
foreach finding (file_matches)
{
install_path = NULL;
file_version = NULL;
version = NULL;
regversion = NULL;
# Derive install path: FilePath - EndsWith suffix
foreach var matching_sig (finding['MatchingSignatures'])
{
if (matching_sig['SigField'] != _file_sig_field) continue;
if (matching_sig['SigOperator'] != _file_sig_op) continue;
var subpath = matching_sig['SigVal'];
install_path = finding['CollectData']['FilePath'] - subpath;
install_path = preg_replace(pattern:"^(.+)\\$", replace:"\1", string:install_path);
break;
}
if (empty_or_null(install_path))
{
dbg::detailed_log(lvl:1, msg:'Could not derive install path from finding',
msg_details:{'filepath':{'lvl':1,'value':finding['CollectData']['FilePath']}});
continue;
}
# Extract ProductVersionString from MatchData
foreach match_data (finding['MatchData'])
{
if (!isnull(_pev_label) && match_data['Label'] == _pev_label)
{
file_version = match_data['Values'][0];
break;
}
}
# Find matching uninstall entry for DisplayVersion fallback
foreach var uninst (uninstall_matches)
{
var uninst_path = uninst['CollectData']['DirPath'];
if (!empty_or_null(uninst_path))
uninst_path = preg_replace(pattern:"^(.+)\\$", replace:"\1", string:uninst_path);
if (tolower(uninst_path) != tolower(install_path)) continue;
regversion = uninst['CollectData']['Version'];
break;
}
version = file_version;
# Fallback to DisplayVersion when ProductVersionString is absent
if (empty_or_null(version) && !isnull(regversion))
{
version = regversion;
}
# For v10+ (2-digit major), prefer DisplayVersion if major matches
else if (!empty_or_null(version) && version !~ '^[0-9]\\.' && !isnull(regversion))
{
var vsplit = split(version, sep:'.', keep:FALSE);
var rvsplit = split(regversion, sep:'.', keep:FALSE);
if (!isnull(vsplit) && !isnull(rvsplit) && rvsplit[0] == vsplit[0])
version = regversion;
}
if (empty_or_null(version)) version = UNKNOWN_VER;
# Apply VersionMin/VersionMax adjustments from Installer registry key
min_val = _path_min[tolower(install_path)];
max_val = _path_max[tolower(install_path)];
su1_val = _path_su1[tolower(install_path)];
vparts = split(version, sep:'.', keep:FALSE);
for (i = 0; i < max_index(vparts); i++)
vparts[i] = int(vparts[i]);
if (!isnull(max_val) && !isnull(min_val))
{
a = (max_val >> 16);
b = max_val & 0xffff;
c = min_val >> 16;
d = min_val & 0xffff;
if (vparts[0] > 7 && vparts[0] == a && vparts[1] == b && vparts[2] < c)
{
vparts[2] = c;
vparts[3] = d;
version = vparts[0] + '.' + vparts[1] + '.' + vparts[2];
}
if (vparts[0] <= 7 && a == 0 && vparts[0] == b && vparts[1] == c && vparts[2] < d)
{
vparts[2] = d;
vparts[3] = 0;
version = vparts[0] + '.' + vparts[1] + '.' + vparts[2];
}
}
# Format display version
pat = "^([0-9]+\.[0-9]+\.[0-9])\.(2[0-9]{3})([0-9]{2})([0-9]{2})([0-9]{2})$";
vm = pregmatch(pattern:pat, string:version);
if (!isnull(vm))
{
if (vparts[0] < 7)
version_ui = vm[1] + ' ' + int(vm[3]) + '/' + int(vm[4]) + '/' + int(vm[2]);
else
version_ui = vm[1];
}
else
{
version_ui = version;
}
if (version =~ "^[0-9]+\.[0-9]+\.2[0-9]+") track = 'DC Continuous';
else if (version =~ "^[0-9]+\.[0-9]+\.3[0-9]+") track = 'DC Classic';
else track = UNKNOWN_VER;
extra = {'Track': track};
extra_nr = {};
if (!empty_or_null(su1_val))
{
extra_nr['812su1Installed'] = su1_val;
extra['Update'] = 'Security Update 1';
}
register_install(
app_name : app,
vendor : vendor,
product : 'Acrobat',
path : install_path,
version : version,
display_version : version_ui,
extra : extra,
extra_no_report : extra_nr,
cpe : cpe
);
}
get_install_count(app_name:app, exit_if_zero:TRUE);
report_installs(app_name: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
17 Aug 2026 00:00Current
5.4Medium risk
Vulners AI Score5.4