code | #
# (C) Tenable Network Security, Inc.
#
include("compat.inc");
if (description)
{
script_id(126263);
script_version("1.3");
script_cvs_date("Date: 2019/12/18");
script_cve_id("CVE-2019-3956");
script_xref(name:"TRA", value:"TRA-2019-26");
script_name(english:"SolarWinds Dameware Mini Remote Control Client Public Key Buffer Over-read");
script_summary(english:"Checks server response");
script_set_attribute(attribute:"synopsis", value:
"The remote host is running a remote control application that is
affected by a buffer over-read vulnerability.");
script_set_attribute(attribute:"description", value:
"The SolarWinds Dameware Mini Remote Control Client Agent running on
the remote host is affected by a buffer over-read vulnerability due
to improper validation of user-supplied data. An unauthenticated,
remote attacker can exploit this, via a series of requests, to cause
a denial of service condition.
Note that the software is reportedly affected by additional
vulnerabilities; however, this plugin has not tested for these.");
# https://support.solarwinds.com/SuccessCenter/s/article/Dameware-Mini-Remote-Control-12-1-0-Hotfix-2-Release-Notes
script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?1220acd8");
script_set_attribute(attribute:"solution", value:
"Upgrade to SolarWinds Dameware Mini Remote Control v12.1 Hotfix 2 or
later, and make sure the DWRCRSS.dll used by the running client
agent (DWRCS.exe) is v12.1.0.89 or later.");
script_set_cvss_base_vector("CVSS2#AV:N/AC:M/Au:N/C:P/I:N/A:P");
script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H");
script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C");
script_set_attribute(attribute:"cvss_score_source", value:"CVE-2019-3956");
script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
script_set_attribute(attribute:"vuln_publication_date", value:"2019/06/06");
script_set_attribute(attribute:"patch_publication_date", value:"2019/06/06");
script_set_attribute(attribute:"plugin_publication_date", value:"2019/06/27");
script_set_attribute(attribute:"plugin_type", value:"remote");
script_set_attribute(attribute:"cpe", value:"cpe:/a:dameware:mini_remote_control");
script_end_attributes();
script_category(ACT_ATTACK);
script_family(english:"Windows");
script_copyright(english:"This script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
script_dependencies("find_service2.nasl");
script_require_ports(6129, "Services/dameware");
exit(0);
}
include('audit.inc');
include('global_settings.inc');
include('misc_func.inc');
include('byte_func.inc');
include('string.inc');
port = get_service(svc:'dameware', default:6129, exit_on_fail:TRUE);
soc = open_sock_tcp(port);
if (! soc) audit(AUDIT_SOCK_FAIL, port);
set_byte_order(BYTE_ORDER_LITTLE_ENDIAN);
#
# On connection, server sends MSG_TYPE_VERSION (0x00001130)
#
res = recv(socket:soc, length:0x28, min:0x28);
if(strlen(res) < 0x28 || getdword(blob:res, pos:0) != 0x1130)
{
close(soc);
exit(1, 'Failed to receive a MSG_TYPE_VERSION message from server on port ' + port + '.');
}
#
# Client sends MSG_TYPE_VERSION (0x00001130)
#
req = mkdword(0x1130)
+ '\x00\x00\x00\x00'
+ '\x00\x00\x00\x00\x00\x00\x28\x40' # ProtocolMajorVersion (12)
+ '\x00\x00\x00\x00\x00\x00\x00\x00' # ProtocolMinorVersion (0)
+ mkdword(4)
+ mkdword(0)
+ mkdword(0)
# AuthType:
# 0 - DW_REQUESTED_AUTHENTICATION_TYPE_BASIC (dwrcs user/pwd)
# 1 - DW_REQUESTED_AUTHENTICATION_TYPE_NTCR (NTLMSSP)
# 2 - DW_REQUESTED_AUTHENTICATION_TYPE_ENCRYPTED (encrypted OS creds)
# 3 - DW_REQUESTED_AUTHENTICATION_TYPE_SMARTCARD
+ mkdword(2);
send(socket:soc, data:req);
#
# Server sends MSG_TYPE_CLIENT_INFORMATION_V7 (0x00011171)
#
res = recv(socket:soc, length:0x3af8, min:0x3af8,timeout:10);
if(strlen(res) < 0x3af8 || getdword(blob:res, pos:0) != 0x11171)
{
close(soc);
exit(1, 'Failed to receive a MSG_TYPE_CLIENT_INFORMATION_V7 message from server on port ' + port + '.');
}
# Client sends MSG_TYPE_CLIENT_INFORMATION_V7 (0x00011171)
# Should be able to use the one sent by the server
send(socket:soc, data:res);
#
# Server sends MSG_TYPE_RSA_CRYPTO_C_INIT (0x000105b8)
#
msg_len = 0x1220;
res = recv(socket:soc, length:msg_len, min:msg_len, timeout:10);
if(strlen(res) < msg_len || getdword(blob:res, pos:0) != 0x105b8)
{
close(soc);
exit(1, 'Failed to receive a MSG_TYPE_RSA_CRYPTO_C_INIT message from server on port ' + port + '.');
}
#
# Client sends MSG_TYPE_RSA_CRYPTO_C_INIT (0x000105b8)
# Should be able to use the one sent by the server
send(socket:soc, data:res);
#
# Server sends Msg 0x000105b9
#
msg_len = 0x2c2c;
res = recv(socket:soc, length:msg_len, min:msg_len, timeout:10);
if(strlen(res) < msg_len || getdword(blob:res, pos:0) != 0x105b9)
{
close(soc);
exit(1, 'Failed to receive a message 0x000105b9 from server on port ' + port + '.');
}
# Get Server public key
pkey_len = getdword(blob:res, pos: 0x140c);
if(pkey_len == 0 || pkey_len > 0x400)
{
close(soc);
exit(1, 'Invalid server DH/ECDH public key size ' + pkey_len + '.');
}
# The vuln is in DWRCRSS.dll, which uses a 16-byte public key.
# If the "Allow only FIPS Mode" setting is enabled, DWRCS.exe loads
# DWRCRSA.dll, which uses a different public key size.
if(pkey_len != 16)
{
close(soc);
exit(0, 'The remote DWRCS.exe does not appear to load DWRCRSS.dll. The remote host is not affected.');
}
srv_pubkey = substr(res, 0x100c, 0x100c + pkey_len -1);
dh_prime = raw_string(
0xF5, 0x1F, 0xFB, 0x3C, 0x62, 0x91, 0x86, 0x5E,
0xCD, 0xA4, 0x9C, 0x30, 0x71, 0x2D, 0xB0, 0x7B
);
dh_gen = raw_string(3);
req = mkdword(0x000105b9);
# Server DH public value at offset 0x100c, up to 0x400 bytes
req += crap(data:'\x00', length:0x100c - strlen(req));
req += rpad(srv_pubkey, 0x400, char:'\x00');
# Length of server DH public value
req += mkdword(strlen(srv_pubkey));
# Client DH public value at offset 0x1418, up to 0x400 bytes
req += crap(data:'\x00', length:0x1418 - strlen(req));
clt_privkey = rand_str(length:16);
# g^x mod p
clt_pubkey = bn_mod_exp(dh_gen, clt_privkey, dh_prime);
req += rpad(clt_pubkey, 0x400, char:'\x00');
# Specify a large length of client DH public value
req += mkdword(0x801);
# Pad to msg_len
req += crap(data:'\x00', length: msg_len - strlen(req));
send(socket:soc, data:req);
res = recv(socket:soc, length:msg_len, timeout:10);
close(soc);
#
# The patched server limits the client DH public key to 0x800 bytes.
# It will drop the connection after seeing the public key size of
# 0x801 bytes.
#
if(isnull(res))
audit(AUDIT_HOST_NOT, 'affected');
# The vulnerable server does not check the client DH public key size.
# It will continue the DH key exchange, sending another 0x105b9 message
# with error code 0.
if(strlen(res) > 12 &&
getdword(blob:res, pos:0) == 0x105b9 &&
getdword(blob:res, pos:8) == 0
)
security_report_v4(port: port,severity: SECURITY_WARNING);
else
audit(AUDIT_RESP_BAD, port);
|