#TRUSTED 2ee1e8cff32f007ca776e87a1bacbc3fa03c25550c495f67502bc40d389643f74419a029a967b0bd4489cdc4fe798fc15d496b8decae24158e667db6b8c995eb9028424ba533d45799689a318f838ef7dc0db7f610b4e59ae9c7a884c2748d3730a52b833f97db6d84cb4572b94cc8199c1c701dec4745020b675c60d273261e20021e1f395b71215c8f1f89a03ec0c7e197871093e3147737040ae2a8ba7dbfcd53cf9094cb1598dbeac097cc59a5be9e463a5800166c04d7c9ad25283fd083ce91fa5feccc87c8e564c0a35f442652dadf9f755cad076fef22a4ad9af471f76e1a9c1b9b01798b07b45fc84edd024a4766a16496c26ae5e9a2d5503232905545189e00e882e7141ab168abb085ce785182997351e823167ff1b66f0288863745f593e6e106ca8b8c19928bb806486c727a105f689f278e54c491022a0906d880e15156a11818604d3eaf1fd0209f579c1ac5fb8b043931ef7f1ec9b60211b20714b1defdb80c651e9273c09571348df90eb3f5e261e1417544e807877457d66578d325e8a930d410f945f6f2d33b2deb11aefb7360136783fc44e779495a2516ed096038773d3348ff23a8bf2120599a9a0d657dcb2a4fbed19da15d231abbe2a3862d70fabfbd43e5cd4b507650e7e7c645c3373f61912d42b09c3caad472098bfbe5febcd5700a07d82033ba95207a0ffc4d09544fbb7dfeb68fd52bcb3f
#TRUST-RSA-SHA256 272ac670927d11f30dadc60d6a6175833465debb7afb6cffa844166b653aaab70c04c1778a57c3848ee1a9d891783721b7915d294b09db6b0f08126e51e4434595a8c1a85a9a5a3e644cee5b42ec4120402a2e74dc40bf7f83849b352a588db82f80f7e84e2af93e7a78309a8ae8caf7f2f1b063123b99b6aaefd15a6ad3167c44b61209e9d39e894d02e5843867184763990f9a35ab691e59c39526fd7a639bd549f407c185696781a82591271adc66ec1c681912b0ac84b8fe3b8fda732aafde29bcc84a5390fd5fe44e53cb1431ee775dc87b7ba23cbc36a9691132730af39841abed1353d8a4954b02b60cb79992ac322b0f78a3526e4472ac88fbbb3fe4bd7ab95fe8d54946d044e365b6846d961d188f76095e654bc737513eddad29ee3c2174c4e07bb5c5d9902ef2861c14b20a98b94d2654ecd1c100b4bb470df20f0b4478e707afe71a7de1a226cd7cf58ab7b560923a7fc113251752b3ef4c14d7cb9fb917948b9168ec691a19b03ad8f587d37abd3db3ca83e708c153141fa536c816b757fac0f305330d823dc7d66fdfdabd06408006a356bf6d3d65027863678170fd5d6de06d3c41dd2a6cf904eae00bb071b9d32923fc8e5acdd288190a5ec76847943aad15a821fbfb5a6ef4614cb65ff4e673883ec3ca92fcad6feca43a5cae02bd2b4b92143ee88a2b4a17dc973bfea88989443d1150e04e82a7e7b59c
##
# (C) Tenable, Inc.
##
include("compat.inc");
if (description)
{
script_id(55932);
script_version("1.30");
script_set_attribute(attribute:"plugin_modification_date", value:"2025/08/13");
script_xref(name:"IAVT", value:"0001-T-0642");
script_name(english:"Junos Version Detection");
script_set_attribute(attribute:"synopsis", value:
"It is possible to obtain the operating system version number of the
remote Juniper device.");
script_set_attribute(attribute:"description", value:
"The remote host is running Junos, an operating system for Juniper
devices.
It is possible to read the Junos version number by logging into the
device via SSH, using SNMP, or viewing the web interface.");
script_set_attribute(attribute:"solution", value:"n/a");
script_set_attribute(attribute:"risk_factor", value:"None");
script_set_attribute(attribute:"plugin_publication_date", value:"2011/08/22");
script_set_attribute(attribute:"plugin_type", value:"combined");
script_set_attribute(attribute:"cpe", value:"cpe:/o:juniper:junos");
script_set_attribute(attribute:"asset_inventory", value:"True");
script_set_attribute(attribute:"hardware_inventory", value:"True");
script_set_attribute(attribute:"os_identification", value:"True");
script_end_attributes();
script_category(ACT_GATHER_INFO);
script_copyright(english:"This script is Copyright (C) 2011-2025 and is owned by Tenable, Inc. or an Affiliate thereof.");
script_family(english:"Junos Local Security Checks");
script_dependencies("ssh_get_info.nasl", "snmp_sysDesc.nasl", "netconf_detect.nbin");
script_require_ports("Host/Juniper/show_ver", "SNMP/sysDesc", "Services/www");
exit(0);
}
include("snmp_func.inc");
include("http.inc");
include('host_os.inc');
include('hardware_registration.inc');
include('os_install.inc');
include('structured_data.inc');
##
# Saves the provided Junos version, build date, model,
# source, port and chassis serial number in the KB,
# generates plugin output, registers os and exits.
#
# @param ver JUNOS version number
# @param build Juniper device type
# @param model Juniper model number
# @param source service used to obtain the version
# @param port Port used in detection (0 for SSH)
#
##
function junos_report_exit(ver, build, model, source, port, serial, node_info)
{
var snj; # Serial Number Juniper
var type, confidence;
var report = '';
var id_data = {};
if (!empty_or_null(node_info))
{
if (!empty_or_null(node_info['node_id']))
{
set_kb_item(name:'Host/Juniper/JUNOS/node', value:node_info['node_id']);
report += '\n Cluster node : ' + node_info['node_id'];
}
if (!empty_or_null(node_info['node_status']))
{
set_kb_item(name:'Host/Juniper/JUNOS/node_status', value:node_info['node_status']);
report += '\n Node status : ' + node_info['node_status'];
}
}
if (!empty_or_null(ver))
{
set_kb_item(name:"Host/Juniper/JUNOS/Version", value:ver);
report += '\n Junos version : ' + ver;
}
if (!empty_or_null(build))
{
set_kb_item(name:"Host/Juniper/JUNOS/BuildDate", value:build);
report += '\n Build date : ' + build;
}
if (!empty_or_null(model))
{
set_kb_item(name:"Host/Juniper/model", value:model);
report += '\n Model : ' + model;
}
if (!empty_or_null(port))
{
set_kb_item(name:"Host/Juniper/JUNOS/Port", value:port);
report += '\n Port : ' + port;
}
if(!empty_or_null(serial))
{
set_kb_item(name:"Host/Juniper/JUNOS/Serial Number", value:serial);
snj = new structured_data_asset_identifier();
# report structured data value
id_data['identifier_source'] = 'juniperSerialNumber';
id_data['identifier_value'] = serial;
id_data['type'] = 'Network Device Serial Identifier';
dbg::detailed_log(lvl:3,
src:SCRIPT_NAME,
msg:'id data found',
msg_details: {
"findings": { "lvl": 3, "value":id_data }
}
);
snj.append('identifier', id_data);
snj.report_internal();
report += '\n Serial : ' + serial;
}
## set os identification
if (!empty_or_null(source))
{
set_kb_item(name:"Host/Juniper/JUNOS/Source", value:source);
report += '\n Source : ' + source;
if (source == 'SSH')
{
if (!empty_or_null(ver))
juniper_os += ver;
type = 'local';
confidence = 100;
host_os_add(method: 'SSH', os: juniper_os, confidence: confidence, type: 'embedded');
}
if (source == 'SNMP')
{
if (!empty_or_null(ver))
juniper_os += ver;
type = 'remote';
confidence = 85;
host_os_add(method: 'SNMP', os: juniper_os, confidence: confidence, type: 'embedded');
}
if (source == 'NETCONF')
{
if (!empty_or_null(ver))
juniper_os += ver;
type = 'remote';
confidence = 85;
host_os_add(method: 'NETCONF', os: juniper_os, confidence: confidence, type: 'embedded');
}
if (source == 'HTTP')
{
if (!empty_or_null(ver))
juniper_os += ver;
type = 'remote';
confidence = 85;
host_os_add(method: 'WebUI', os: juniper_os, confidence: confidence, type: 'embedded');
}
}
var vendor = 'Juniper';
var product = 'Junos';
var os_name = strcat(vendor, ' ', product);
var cpe = 'cpe:/o:juniper:junos:';
var display_version, version, update;
# Parse out the 'release' as the 'update' to match CPEs
# - Examples:
# - 18.4R2-S9 => cpe:/o:juniper:junos:18.4:r2-s9
# - 15.1X53-D25 => cpe:/o:juniper:junos:15.1x53:d25
var pattern = '^([0-9]+\\.[0-9X]+)-?([A-WYZ][A-Z0-9.-]+)';
var matches = pregmatch(string:ver, pattern:pattern, icase:TRUE);
if (!empty_or_null(matches))
{
display_version = matches[0];
version = matches[1];
update = matches[2];
}
register_os(
type : type,
method : source,
confidence : confidence,
port : port,
vendor : vendor,
product : product,
version : version,
display_version : display_version,
update : update,
os_name : os_name,
cpe : cpe
);
if (!empty_or_null(model))
{
var full_name = strcat(vendor, ' ', model);
cpe = 'cpe:/h:juniper:' + model;
register_hardware(
type : type,
method : source,
confidence : confidence,
port : port,
category : 'system',
full_name : full_name,
vendor : vendor,
product : model,
serial_number : serial,
cpe : cpe
);
}
security_report_v4(severity:SECURITY_NOTE, port:port, extra:report);
exit(0);
}
var juniper_os = 'Juniper Junos ';
# 1. SSH
# Device like the SRX series can be clustered. If so, the have two nodes which are separate
# devices, but the SSH command outputs contain information for both nodes. The nodes are always
# named node0 and node1. Either can be "primary" or secondary - REF: CS-71588
# Determine which node we are on
var is_node_0 = FALSE;
var is_node_1 = FALSE;
var is_primary = FALSE;
var is_secondary = FALSE;
var cluster = FALSE;
var node_info = {};
var post_login_buf = get_kb_list('SSH/*/post_login_buffer');
var node_pat = "{(primary|secondary):(node0|node1)}";
# I can't say with certainty that the post_login_buffer KB item only ever appears once
# In theory, this should be fine even if there is more than one item, as one would assume
# that the banner will always be the same, regardless of session ID (because, same host)?
var item, val, node_match;
for (item in post_login_buf)
{
val = post_login_buf[item];
node_match = pregmatch(multiline:TRUE , pattern:node_pat , string:val);
# Check if we are on primary or secondry node
if (node_match[1] == 'primary')
{
is_primary = TRUE;
node_info['node_status'] = 'Primary';
}
else if (node_match[1] == 'secondary')
{
is_secondary = TRUE;
node_info['node_status'] = 'Secondary';
}
# Check if we are on node0 oe node1
if (node_match[2] == 'node0')
{
is_node_0 = TRUE;
node_info['node_id'] = 'node0';
}
else if (node_match[2] == 'node1')
{
is_node_1 = TRUE;
node_info['node_id'] = 'node1';
}
}
var showver = get_kb_item("Host/Juniper/show_ver");
# If dealing with cluster, we only want the portion of the command outputs that are relevant to the node we are on
var split_output_pat = "(^node0:.*)(node1:.*$)";
var split_showver = pregmatch(multiline:TRUE, pattern:split_output_pat, string:showver);
var showver_node0, showver_node1;
if (split_showver[1] && split_showver[2])
{
cluster = TRUE;
if (split_showver[1] =~ "^node0")
{
showver_node0 = split_showver[1];
if (is_node_0)
{
showver = showver_node0;
}
}
if (split_showver[2] =~ "^node1")
{
showver_node1 = split_showver[2];
if (is_node_1)
{
showver = showver_node1;
}
}
}
var register_junos_os = FALSE;
var model, junos, port, hardware_extensive, he_model, kernel, he_serial, serial,
report, desc, build, community, soc, device, ports, res, match, split_hardware_extensive;
if (showver)
{
model = pregmatch(string:showver, pattern:'Model: +(.+)');
junos = pregmatch(string:showver, pattern:'Junos: (.+)');
port = 0; #SSH port is considered local
hardware_extensive = get_kb_item("Host/Juniper/show_chassis_hardware_extensive");
if (cluster)
{
split_hardware_extensive = pregmatch(pattern:split_output_pat, string:hardware_extensive, multiline:TRUE);
if (split_hardware_extensive[1] && split_hardware_extensive[2])
{
if (is_node_0)
{
hardware_extensive = split_hardware_extensive[1];
}
if (is_node_1)
{
hardware_extensive = split_hardware_extensive[2];
}
}
}
if (!empty_or_null(hardware_extensive))
{
he_model = pregmatch(string:hardware_extensive, pattern:'FRU Model Number: +(.+)');
if (!empty_or_null(he_model) && !empty_or_null(he_model[1]))
model = he_model;
# Grab chassis serial number
he_serial = pregmatch(string:hardware_extensive, pattern:"Chassis\s+([A-Za-z0-9]+)\s");
if(!empty_or_null(he_serial) && !empty_or_null(he_serial[1]))
{
serial = he_serial[1];
}
}
# Get approximate Date of Build from Junos build version
# example: MGD release 16.2R2-S1 built by builder on 2017-08-25 04:07:53 UTC
if (junos)
{
kernel = pregmatch(string:showver, pattern:'(' + junos[1] + ') .+on ([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) .+');
}
# Get Date ond approximate version of Build
# example: KERNEL 16.2R2-S1 built by builder on 2019-18-18 12:01:53 UTC
else
{
kernel = pregmatch(string:showver, pattern:'KERNEL ([^ ]+) .+on ([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])');
}
if (model && kernel)
{
set_kb_item(name:"Host/Juniper/kernel", value:kernel[0]);
junos_report_exit(ver:kernel[1], build:kernel[2], model:toupper(model[1]), source:'SSH', port:0, serial:serial, node_info:node_info);
}
}
# 2. SNMP
desc = get_kb_item("SNMP/sysDesc");
if (desc)
{
junos = pregmatch(string:desc, pattern:"JUNOS ([0-9.]+[^ ,]+)");
build = pregmatch(string:desc, pattern:"Build date: ([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])");
# if the Junos version was obtained via SNMP, try to get the model as well
if (junos && build)
{
community = get_kb_item_or_exit("SNMP/community");
port = get_kb_item("SNMP/port");
if(!port) port = 161;
if (!get_udp_port_state(port)) exit(0, "UDP port "+port+" is not open.");
soc = open_sock_udp(port);
if (!soc) exit (0, "Failed to open a socket on port "+port+".");
device = snmp_request(socket:soc, community:community, oid:"1.3.6.1.4.1.2636.3.1.2.0");
close(soc);
if (device)
{
# e.g. Juniper J2350 Internet Router
model = pregmatch(string:device, pattern:"^Juniper ([^ ]+)");
if (empty_or_null(model) && empty_or_null(model[1]))
model[1] = 'n/a';
}
junos_report_exit(ver:junos[1], build:build[1], model:toupper(model[1]), source:'SNMP', port:port);
}
}
# 3. NETCONF
if (get_kb_item('Host/netconf/junos'))
{
var netconf_port = get_kb_item('Host/netconf/port');
# try and get hardware model and firmware version from 'show versions' output.
var versions = get_kb_item('Host/netconf/junos/versions');
if (!empty_or_null(versions))
{
var version_check = pregmatch(pattern:"JUNOS: ([A-Z0-9\.-]+)(?:-S[0-9\.]+)?(?:\sFLEX)?",string:toupper(versions));
var model_check = pregmatch(pattern:'MODEL: ([A-Z]+)',string:toupper(versions));
if (empty_or_null(version_check) && empty_or_null(version_check[1]))
version_check[1] = 'n/a';
if (empty_or_null(model_check) && empty_or_null(model_check[1]))
model_check[1] = 'n/a';
junos_report_exit(ver:toupper(version_check[1]), model:toupper(model_check[1]), source:'NETCONF', port:netconf_port);
}
}
# 4. Web (only older versions allow us to view the version w/o authenticating)
var ui_ports = get_kb_list('Services/www');
if (isnull(ui_ports)) exit(0, 'The "Services/www" KB item is missing.');
foreach port (ui_ports)
{
var http_cache = http_get_cache(port:port, item:'/', exit_on_fail:TRUE);
if ('juniper networks' >!< tolower(http_cache) || 'juniper web device' >!< tolower(http_cache) || 'juniper.net' >!< tolower(http_cache))
{
dbg::detailed_log(lvl:2, msg:'No indication of Juniper was found in the web server\'s cache on port ' + port);
continue;
}
res = http_send_recv3(method:'GET', item:'/login', port:port, exit_on_fail:TRUE);
dbg::detailed_log(lvl:3, msg:'Request sent: ' + http_last_sent_request());
dbg::detailed_log(lvl:3, msg:'Response recieved: ' + res[0] + res[1] + res[2]);
# Parse for the model
match = pregmatch(string:res[2], pattern:'<div class="jweb-title uppercase">.* - ([^<]+)</div>|\\.productVersion = \'(.+)\'');
if (!isnull(match))
{
if (!isnull(match[1])) model = toupper(match[1]);
else model = toupper(match[2]);
}
# Parse for the version
match = pregmatch(string:res[2], pattern:'src=\\"\\/extjs\\/ext-all\\.js\\?ver=([^"]+)\\"><\\/script>');
if (!isnull(match) && !isnull(match[1]))
junos = match[1];
else if (!isnull(model))
{
# Final attempt to pull the version
res = http_send_recv3(method:'GET', item:'/about', port:port, exit_on_fail:TRUE);
dbg::detailed_log(lvl:3, msg:'Request sent: ' + http_last_sent_request());
dbg::detailed_log(lvl:3, msg:'Response recieved: ' + res[0] + res[1] + res[2]);
match = pregmatch(string:res[2], pattern:'Version (.+) *built by [^ ]+ on ([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])');
if (isnull(match))
{
junos = 'n/a';
dbg::detailed_log(lvl:2, msg:'Unable to get Junos version from the web interface, authentication may be required.');
}
else
{
junos = match[1];
build = match[2];
}
}
junos_report_exit(ver:junos, build:build, model:toupper(model), source:'HTTP', port:port);
}
exit(0, "The Junos version is not available.");
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