Lucene search

K
nessusThis script is Copyright (C) 2020-2022 and is owned by Tenable, Inc. or an Affiliate thereof.IBM_SPECTRUM_PROTECT_CVE-2019-4087.NASL
HistoryMar 13, 2020 - 12:00 a.m.

IBM Spectrum Protect Server and Storage Agent RCE

2020-03-1300:00:00
This script is Copyright (C) 2020-2022 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
76

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

0.019 Low

EPSS

Percentile

88.5%

The IBM Spectrum Protect server or storage agent running on the remote host is affected by a remote code execution vulnerability due to improper invalidation of user-supplied data during communication exchanges. An unauthenticated, remote attacker can exploit this, via a series of specially crafted messages, to execute arbitrary code on the system with instance id privileges or cause the server or storage agent to crash.

#%NASL_MIN_LEVEL 70300
#
# (C) Tenable Network Security, Inc.
#

include('deprecated_nasl_level.inc');
include('compat.inc');

if (description)
{
  script_id(134564);
  script_version("1.4");
  script_set_attribute(attribute:"plugin_modification_date", value:"2022/07/06");

  script_cve_id("CVE-2019-4087", "CVE-2019-4088");

  script_name(english:"IBM Spectrum Protect Server and Storage Agent RCE");

  script_set_attribute(attribute:"synopsis", value:
"A backup service running on the remote host is affected by a
remote code execution vulnerability.");
  script_set_attribute(attribute:"description", value:
"The IBM Spectrum Protect server or storage agent running on the
remote host is affected by a remote code execution vulnerability due
to improper invalidation of user-supplied data during communication
exchanges. An unauthenticated, remote attacker can exploit this, via
a series of specially crafted messages, to execute arbitrary code on
the system with instance id privileges or cause the server or storage
agent to crash.");
  script_set_attribute(attribute:"see_also", value:"https://www.ibm.com/support/pages/node/882472");
  script_set_attribute(attribute:"solution", value:
"Upgrade to IBM Spectrum Protect 7.1.9.300 or 8.1.8 or later.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C");
  script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
  script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/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-4087");

  script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");

  script_set_attribute(attribute:"vuln_publication_date", value:"2019/06/28");
  script_set_attribute(attribute:"patch_publication_date", value:"2019/06/28");
  script_set_attribute(attribute:"plugin_publication_date", value:"2020/03/13");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:ibm:tivoli_storage_manager");
  script_set_attribute(attribute:"cpe", value:"x-cpe:/a:ibm:spectrum_protect");
  script_set_attribute(attribute:"thorough_tests", value:"true");
  script_end_attributes();

  script_category(ACT_ATTACK);
  script_family(english:"General");

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

  script_dependencies("ibm_tsm_detect.nasl");
  script_require_ports("tsm-agent", 1500);

  exit(0);
}

include('byte_func.inc');

##
# Send a 'verb' request.
#
# @param socket Socket to send the verb.
# @param code Verb code.
# @param data Verb data.
#
# @return None
##
function send_verb (socket, code, data)
{
 local_var header, len, req;

  len = strlen(data);

  if(code < 0x100)
  {
    header =
      mkword(len+4) +
      mkbyte(code) +
      mkbyte(0xa5);  # magic
  }
  else
  {
    header =
      mkword(0) +
      mkbyte(8) +
      mkbyte(0xa5)  +
      mkdword(code) +
      mkdword(len+12);
  }
  
 req = header + data;
 send(socket:socket, data:req);
}

##
# Receive a 'verb' response.
#
# @param socket Socket to receive the response.
#
# @return {"code":<verb_code>, "data":<verb_data>} or NULL on error.
#
##
function recv_verb(socket)
{
 local_var code, header, data, len;

 header = recv(socket:socket, length:4, min:4, timeout:10);
 if (isnull(header)) return NULL;

 # We expect at least 4 bytes
 if(strlen(header) < 4) return NULL;

 # Check magic byte
 if (ord(header[3]) != 0xa5) return NULL;

 # Get the verb code 
 code = ord(header[2]);

 # Got an extended verb code
 if(code == 8)
 {
  header = recv(socket:socket, length:8, min:8, timeout:10);
  if (isnull(header) || strlen(header) < 8) return NULL;

  code = getdword(blob:header, pos:0);
  len  = getdword(blob:header, pos:4);
  if (len < 12) return NULL;
  len = len - 12;
 }
 else
 {
  len = getword(blob:header, pos:0);
  if (len < 4) return NULL;
  len = len - 4;
 }

 data = recv(socket:socket, length:len, min:len, timeout:10);

 return {'code':code, 'data':data};
}

port = get_service(svc:'tsm-agent', default:1500, exit_on_fail:TRUE);

if(get_port_transport(port) == ENCAPS_IP)
  ssl = FALSE;
else
  ssl = TRUE;

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

# Send the Identify verb message.
#
# Need to send this verb message so that the server is in the right
# state to process the subsequent Negotiate verb message.
send_verb(socket:soc, code:0x1d, data:NULL);
res = recv_verb(socket:soc);
if(isnull(res) || res.code != 0x1e)
{
  close(soc);
  exit(1, 'Failed to receive a IdentifyResp message.');
}

# Send the Negotiate verb message.
#
# Need to send this verb message so that the server is in the right
# state to process the subsequent TransportMethod verb message.
user = 'nessus';
data = mkbyte(1) +      # version
  mkword(0x1b) +        # dataOffset to user from msg start
  mkdword(0x40000000) + # supportedMethods
  mkword(2) +           # sslMode
  mkword(0) +           # username offset within 'data'?
  mkword(strlen(user)) +  # username length
  mkbyte(1) +           # idType
  mkbyte(7) +           # sessType
  user;                 # username
send_verb(socket:soc, code:0x3E0000, data:data);
res = recv_verb(socket:soc);
if(isnull(res) || res.code != 0x3E0010)
{
  close(soc);
  exit(1, 'Failed to receive a NegotiateResp message.');
}

# Send the TransportMethod verb message.
#
# This verb is used to switch transport method (i.e., TCP to SSL)
#
# To detect the vulnerability, we send the verb message with:
#
#  1) The transport to switch to matches the current transport.
#     For example, if the plugin currently uses SSL to communicate
#     with the server, it requests to switch to SSL. Similarly, if
#     it is on TCP, it requests to switch to TCP.
#  2) Total verb message length > 19 bytes.
#
# The vulnerable server does not check the verb message length, and it
# continues to process the verb message but does nothing because we
# requested to switch to the same transport we are currently on.
# As a result, it will continue to process our subsequent Authenticate
# verb message, which will result in a AuthenticateResp verb message
# from the server.
#
# The patched server checks the verb message length to ensure it
# doesn't exceed 19 bytes. If so, it shuts down the connection
# without processing any subsequent incoming verb messages.
# As a result, the patched server will not respond to our
# Authenticate verb message.
#
if (ssl)
  new_transport = 2;
else
  new_transport = 1;
data = mkbyte(1) +  # version
  mkword(0xf) +     # dataOffset to transport from msg start
  mkdword(new_transport) +  # Transport to switch to
                            # 1 - TCP, 2 - SSL
  'A';  # Extra data to cause length check failure on the patched
        # server but no crash on the vulnerable server.
send_verb(socket:soc, code:0x3E0040, data:data);

# Send the Authenticate verb message.
pass = SCRIPT_NAME;
pass += crap(data:'\x00', length:0x40 - strlen(pass));
data = mkbyte(1) +        # version
  mkword(0x13) +          # dataOffset to password from msg start
  mkdword(0) +            # password offset within 'data'?
  mkword(strlen(pass)) +  # password length
  pass;                   # password
send_verb(socket:soc, code:0x3E0020, data:data);
res = recv_verb(socket:soc);
close(soc);

# Got a AuthenticateResp: vulnerable
if(!isnull(res) && res.code == 0x3E0030)
{
  extra = "Nessus was able to detect the vulnerability by sending a specially crafted 'TransportMethod' message to the remote service listening on port " + port + '.';
  security_report_v4(
    port      : port,
    severity  : SECURITY_HOLE,
    extra     : extra
  );
}
else
  audit(AUDIT_HOST_NOT, 'affected');
VendorProductVersionCPE
ibmtivoli_storage_managercpe:/a:ibm:tivoli_storage_manager
ibmspectrum_protectx-cpe:/a:ibm:spectrum_protect

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

0.019 Low

EPSS

Percentile

88.5%

Related for IBM_SPECTRUM_PROTECT_CVE-2019-4087.NASL