| Source | Link |
|---|---|
| netiq | www.netiq.com/products/privileged-account-manager/ |
#
# (C) Tenable Network Security, Inc.
#
include("compat.inc");
if (description)
{
script_id(62989);
script_version("1.6");
script_cvs_date("Date: 2019/11/22");
script_name(english:"NetIQ Privileged User Manager Detection");
script_summary(english:"Detects NetIQ Privileged User Manager web application");
script_set_attribute(attribute:"synopsis", value:
"The remote host is running a web administration application for a
system that stores, manages, and delegates privileged user credentials.");
script_set_attribute(attribute:"description", value:
"The remote host is running NetIQ Privileged User Manager. NetIQ
Privileged User Manager is an application for securely storing
credentials for privileged user accounts and delegating access to
network hosts and devices.");
script_set_attribute(attribute:"see_also", value:"https://www.netiq.com/products/privileged-account-manager/");
script_set_attribute(attribute:"solution", value:"n/a");
script_set_attribute(attribute:"risk_factor", value:"None");
script_set_attribute(attribute:"plugin_publication_date", value:"2012/11/21");
script_set_attribute(attribute:"plugin_type", value:"remote");
script_set_attribute(attribute:"cpe", value:"cpe:/a:netiq:privileged_user_manager");
script_set_attribute(attribute:"asset_inventory", value:"True");
script_end_attributes();
script_category(ACT_GATHER_INFO);
script_family(english:"CGI abuses");
script_copyright(english:"This script is Copyright (C) 2012-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
script_dependencies("http_version.nasl");
script_exclude_keys("Settings/disable_cgi_scanning");
script_require_ports("Services/www", 80, 443);
exit(0);
}
include("audit.inc");
include("byte_func.inc");
include("global_settings.inc");
include("misc_func.inc");
include("http.inc");
include("webapp_func.inc");
# app runs on port 443 by default, but can be configured to run on port 80
port = get_http_port(default:80);
appname = "NetIQ Privileged User Manager";
kb_appname = "netiq_pum";
init_cookiejar();
# Start with a GET request to make sure we're looking at the proper service before sending POST requests
res = http_send_recv3(
method:'GET',
item:'/',
port:port,
exit_on_fail:TRUE
);
# Exit unless we are looking at correct application
if (
isnull(res[2]) ||
"<title>NetIQ Privileged User Manager</title>" >!< res[2] ||
"Base.swf" >!< res[2]
) audit(AUDIT_WEB_APP_NOT_INST, appname, port);
# AMF encoded request to get version information (sent when loading 'about.swf')
# It returns a lot of data (including license information), but we are only interested in the version
# number ("vmr" field) which is sent as a string and service name ("svc" field) which is also sent as a
# string
postdata = raw_string(
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x13,0x53, # // . .......S
0x50,0x46,0x2e,0x55,0x74,0x69,0x6c,0x2e,0x63,0x61,0x6c,0x6c,0x4d,0x6f,0x64,0x75, # // PF.Util. callModu
0x6c,0x65,0x00,0x02,0x2f,0x31,0x00,0x00,0x00,0x40,0x0a,0x00,0x00,0x00,0x01,0x03, # // le../1.. .@......
0x00,0x03,0x70,0x6b,0x74,0x03,0x00,0x06,0x6d,0x65,0x74,0x68,0x6f,0x64,0x02,0x00, # // ..pkt... method..
0x0a,0x67,0x65,0x74,0x4c,0x69,0x63,0x65,0x6e,0x73,0x65,0x00,0x06,0x6d,0x6f,0x64, # // .getLice nse..mod
0x75,0x6c,0x65,0x02,0x00,0x08,0x72,0x65,0x67,0x69,0x73,0x74,0x72,0x79,0x00,0x03, # // ule...re gistry..
0x75,0x69,0x64,0x06,0x00,0x00,0x09,0x00,0x00,0x09,0x00,0x13,0x53,0x50,0x46,0x2e, # // uid..... ....SPF.
0x55,0x74,0x69,0x6c,0x2e,0x67,0x65,0x74,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x00, # // Util.get Version.
0x02,0x2f,0x32,0x00,0x00,0x00,0x14,0x0a,0x00,0x00,0x00,0x01,0x03,0x00,0x08,0x69, # // ./2..... .......i
0x64,0x65,0x6e,0x74,0x69,0x74,0x79,0x06,0x00,0x00,0x09 # // dentity. ...
);
res = http_send_recv3(
method:'POST',
item:'/',
port:port,
add_headers:make_array(
'Content-Type', 'application/x-amf', # required
'x-flash-version', '11,4,402,278'
),
data:postdata,
exit_on_fail:TRUE
);
version = UNKNOWN_VER;
# try to parse out version
vrm_search = raw_string(
0x00, 0x03, # length
0x76, 0x72, 0x6d, # "vrm"
0x02 # string is next
);
pos = stridx(res[2], vrm_search);
if (vrm_search >< res[2] && pos >= 0)
{
len = getword(blob:res[2], pos:pos+strlen(vrm_search));
if (len == NULL) exit(1, "The response from port "+port+" is not long enough to contain the length of a version string.");
if (strlen(res[2]) < pos + strlen(vrm_search) + 2 + len) exit(1, "The response from port "+port+" is not long enough to contain a version string.");
version = substr(res[2], pos + strlen(vrm_search) + 2, pos + strlen(vrm_search) + 2 + len - 1);
}
# try to parse out service name
svc_str = '';
svc_search = raw_string(
0x00, 0x03, # length
0x73, 0x76, 0x63, # "svc"
0x02 # string is next
);
if(svc_search >< res[2])
pos = stridx(res[2], svc_search);
if(svc_search >< res[2] && pos && !isnull(pos))
{
len = getword(blob:res[2], pos: pos + strlen(svc_search));
if(len == NULL)
exit(1, 'The response is not long enough to contain length of service string.');
if(strlen(res[2]) < pos + strlen(svc_search) + 2 + len)
exit(1, 'The response is not long enough to contain service string.');
svc_str = substr(res[2], pos + strlen(svc_search) + 2, pos + strlen(svc_search) + 2 + len - 1);
set_kb_item(name:"www/" + port + "/" + kb_appname + "/svc_str", value:svc_str);
}
post_data =
raw_string (0x00, 0x00, 0x00, 0x00, 0x00, 0x01) +
raw_string(0x00,0x13) + # len
"SPF.Util.callModule" +
raw_string(0x00, 0x03, 0x2f, 0x33, 0x30, 0x00, 0x00,
0x02, 0x16, 0x0a, 0x00, 0x00, 0x00, 0x01) +
raw_string(0x03) + # obj
raw_string(0x00, 0x03) + #len
"pkt" +
raw_string(0x03) + # obj
raw_string(0x00, 0x06) + # len
"Engine" +
raw_string(0x03) + # obj
raw_string(0x00, 0x00, 0x09) + # end obj
raw_string(0x00, 0x05) + # len
"Patch" +
raw_string(0x03) + # obj
raw_string(0x00, 0x00, 0x09) + # end obj
raw_string(0x00, 0x06) + # len
"Module" +
raw_string(0x03) + # obj
raw_string(0x00, 0x00, 0x09) + # end obj
raw_string(0x00, 0x07) + # len
"Console" +
raw_string(0x03) + # obj
raw_string(0x00, 0x00, 0x09) + # end obj
raw_string(0x00, 0x06) + # len
"method" +
raw_string(0x02) + # str
raw_string(0x00, 0x0c) + # len
"listPackages" +
raw_string(0x00, 0x06) + # len
"module" +
raw_string(0x02) + # str
raw_string(0x00, 0x06) + # len
"pkgman" +
raw_string(0x00, 0x00, 0x09) + # end obj
raw_string(0x00, 0x00, 0x09); # end obj
res = http_send_recv3(
method:'POST',
item:'/Base.swf',
port:port,
add_headers:make_array(
'Content-Type', 'application/x-amf', # required
'x-flash-version', '11,4,402,278'
),
data:post_data,
exit_on_fail:TRUE
);
cur_pos = 0;
package_search = raw_string(
0x00, 0x05, # length
0x54, 0x69, 0x74, 0x6c, 0x65, # 'Title'
0x03, # obj
0x00, 0x07,
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, # 'Content'
0x02 # str next
);
version_search = raw_string(
0x00, 0x07, # length
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, # 'version'
0x02 # str next
);
pos = stridx(res[2], package_search);
package_version = make_array();
# the default configuration of this software allows package information to be
# retrieved without authentication via the 'listPackages' method
while(pos != -1 &&
version_search >< res[2] &&
package_search >< res[2])
{
package_title = '';
if(pos != -1)
{
len = getword(blob:res[2], pos: pos + strlen(package_search));
if(len == NULL)
continue;
if(strlen(res[2]) < pos + strlen(package_search) + 2 + len)
continue;
package_title = substr(res[2], pos + strlen(package_search) + 2, pos + strlen(package_search) + 2 + len - 1);
cur_pos = pos + strlen(package_search) + 2 + len;
pos_ver = stridx(res[2], version_search, cur_pos);
if(pos_ver == -1)
continue;
len = getword(blob:res[2], pos: pos_ver + strlen(version_search));
if(len == NULL)
continue;
if(strlen(res[2]) < pos_ver + strlen(version_search) + 2 + len)
continue;
# grab version info and convert to x.x.x.x format rather than x,x,x,x
pkg_version = substr(res[2], pos_ver + strlen(version_search) + 2, pos_ver + strlen(version_search) + 2 + len - 1);
pkg_version = str_replace(string:pkg_version, find: ',', replace: '.');
# we are might have to use the version info in ver_compare, so make sure it is the correct format
if(pkg_version !~ "^[0-9][0-9.]+[0-9]$")
continue;
if(!isnull(package_version[package_title]))
{
# versions for same title should all be the same, but just in case, use the latest
if(ver_compare(ver:package_version[package_title], fix:pkg_version, strict:FALSE) == -1)
package_version[package_title] = pkg_version;
}
else
package_version[package_title] = pkg_version;
pos = stridx(res[2], package_search, cur_pos);
}
}
module_info = '';
foreach package (keys(package_version))
{
# reformat package title
package_title = tolower(package);
package_title = str_replace(string:package_title, find:' ', replace: '_');
# reformat
temp_arr = split(package_version[package], sep:'.' , keep:FALSE);
if(max_index(temp_arr) < 5 && max_index(temp_arr) > 3)
{
pkg_str_version = temp_arr[0] + '.' + temp_arr[1] + '.' + temp_arr[2];
if(max_index(temp_arr) == 4)
pkg_str_version += ('-' + temp_arr[3]);
}
else
pkg_str_version = pkg_version;
set_kb_item(name:"www/" + port + "/" + kb_appname + "/packages/" + package_title, value:package_version[package]);
module_info += '\n Name : ' + package +
'\n Version : ' + pkg_str_version + '\n';
}
# Register install
installs = add_install(
installs:NULL,
ver:version,
dir:'/',
appname:kb_appname,
port:port,
cpe: "cpe:/a:netiq:privileged_user_manager"
);
if (report_verbosity > 0)
{
report = '\n URL : ' + build_url(qs:'/', port:port) +
'\n Version : ' + version;
if(module_info != '')
report += '\n\n Installed Packages : ' + module_info;
security_note(port:port, extra:report);
}
else security_note(port);
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