Lucene search

K
nessusThis script is Copyright (C) 2020-2023 and is owned by Tenable, Inc. or an Affiliate thereof.MICROSOFT_SMB_CVE-2020-0796.NASL
HistoryApr 02, 2020 - 12:00 a.m.

Microsoft Windows SMBv3 Compression RCE (ADV200005)(CVE-2020-0796)(Remote)

2020-04-0200:00:00
This script is Copyright (C) 2020-2023 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
192

A remote code execution vulnerability exists in Microsoft Server Message Block 3.1.1 (SMBv3) protocol due to how it handles a maliciously crafted compressed data packet. An unauthenticated, remote attacker can exploit this to bypass authentication and execute arbitrary commands.

Note that this plugin works only if it can to connect to the IPC$ share anonymously using SMB dialect 3.1.1.

#
# (C) Tenable Network Security, Inc.
#

include('compat.inc');

if (description)
{
  script_id(135177);
  script_version("1.7");
  script_set_attribute(attribute:"plugin_modification_date", value:"2023/02/23");

  script_cve_id("CVE-2020-0796");
  script_xref(name:"MSKB", value:"4551762");
  script_xref(name:"MSFT", value:"MS20-4551762");
  script_xref(name:"CISA-KNOWN-EXPLOITED", value:"2022/08/10");
  script_xref(name:"CEA-ID", value:"CEA-2020-0028");

  script_name(english:"Microsoft Windows SMBv3 Compression RCE (ADV200005)(CVE-2020-0796)(Remote)");

  script_set_attribute(attribute:"synopsis", value:
"The remote Windows host is using a vulnerable version of SMB.");
  script_set_attribute(attribute:"description", value:
"A remote code execution vulnerability exists in Microsoft Server Message Block
3.1.1 (SMBv3) protocol due to how it handles a maliciously crafted compressed
data packet. An unauthenticated, remote attacker can exploit this to bypass
authentication and execute arbitrary commands.

Note that this plugin works only if it can to connect to the IPC$
share anonymously using SMB dialect 3.1.1.");
  # https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0796
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?32926bb8");
  script_set_attribute(attribute:"solution", value:
"Apply Cumulative Update KB4551762.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P");
  script_set_cvss_temporal_vector("CVSS2#E:H/RL:OF/RC:C");
  script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H");
  script_set_cvss3_temporal_vector("CVSS:3.0/E:H/RL:O/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2020-0796");

  script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"true");
  script_set_attribute(attribute:"exploit_framework_core", value:"true");
  script_set_attribute(attribute:"exploited_by_malware", value:"true");
  script_set_attribute(attribute:"metasploit_name", value:'SMBv3 Compression Buffer Overflow');
  script_set_attribute(attribute:"exploit_framework_metasploit", value:"true");
  script_set_attribute(attribute:"exploit_framework_canvas", value:"true");
  script_set_attribute(attribute:"canvas_package", value:"CANVAS");

  script_set_attribute(attribute:"vuln_publication_date", value:"2020/03/12");
  script_set_attribute(attribute:"patch_publication_date", value:"2020/03/12");
  script_set_attribute(attribute:"plugin_publication_date", value:"2020/04/02");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"cpe:/o:microsoft:windows");
  script_end_attributes();

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

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

  script_dependencies("smb_dialects_enabled.nasl", "os_fingerprint.nasl", "samba_detect.nasl");
  script_require_keys("SMB/smb_dialect/3.1.1/compression");
  script_exclude_keys("SMB/samba");
  script_require_ports(139, 445);

  exit(0);
}

include('smb_func.inc');
include('agent.inc');

##
# Receive an SMB message starting with the header.
#
# @return SMB response message or NULL on error.
##
function my_smb2_recv()
{
  local_var socket, timeout, length, trailer, ret, header;

  socket = session_get_socket ();
  timeout = session_get_timeout ();

  length = recv(socket:socket, length:4, min:4, timeout:timeout);
  if (strlen(length) != 4)
    return NULL;

  length = 65535 * ord(length[1]) +
           256 * ord(length[2]) +
           ord(length[3]);

  if (length > 100000)
    length = 100000;

  trailer = recv(socket:socket, length:length, min:length, timeout:timeout);
  if (strlen(trailer) < length )
    return NULL;

  return trailer;
}


#
# MAIN
#

# Exit if run on agent.
if(agent()) exit(0,'This plugin is disabled on Nessus Agents.');

# Exit if samba is detected.
if (get_kb_item('SMB/samba') ) exit(0, 'SMB server is Samba.');

# If OS is detected, exit if the OS is not Windows.
os = get_kb_item('Host/OS');
if (os && os !~ '[Ww]indows')
  audit(AUDIT_OS_NOT, 'Windows');

# Exit if SMB v3.1.1 is not supported
if(! get_kb_item('SMB/smb_dialect/3.1.1'))
  exit(0, 'SMB dialect 3.1.1 is not supported on the remote host.');

# Exit if compression is not supported or enabled.
if(! get_kb_item('SMB/smb_dialect/3.1.1/compression'))
  exit(0, 'SMB compression is not supported or enabled on the remote host.'); 

# Exit if LZNT1 compression is not supported or enabled.
if(! get_kb_item('SMB/smb_dialect/3.1.1/compression/LZNT1'))
  exit(0, 'SMB compression algorithm LZNT1 is not supported or enabled on the remote host.');

port = kb_smb_transport();

# SMB transport port isn't open
if (!get_port_state(port))
  audit(AUDIT_PORT_CLOSED, port);

if (!smb_session_init(timeout:10)) audit(AUDIT_FN_FAIL, 'smb_session_init');
soc = session_get_socket();

ret = NetUseAdd(share:'IPC$');
if(ret != 1)
  exit(0, 'Failed to connect to IPC$ anonymously using SMB v3.1.1.');

LZNT1 = 1;
# 0x800135 'A's compressed with LZNT1
orig_size = 0x800135;

compressed = NULL;
# 0x800000 'A's
for (i = 0; i < 0x800; i++)
  compressed += '\x03\xb0\x02\x41\xfc\x0f'; # 0x1000 'A's

# 0x135 'A's
compressed += '\x03\xb0\x02\x41\x31\x01';

# Use TREE_CONNECT as the first message in a compound request to
# avoid crash in srv2.sys versions prior to 10.0.18362.329.
path = 'IPC$';
cpath = cstring (string:"\\", _null:1) + cstring (string:session_get_hostname(), _null:1) + cstring (string:"\", _null:1) + cstring (string:path, _null:1);

data = raw_word(w:9)             + # StructureSize
       raw_word(w:0)             + # Reserved
       raw_word(w:0x48)          + # PathOffset
       raw_word(w:strlen(cpath)) + # PathLength
       cpath;                      # Buffer

# Messages in a compound request are 8-byte aligned. 
if(strlen(data) % 8)
  data += crap(data:'\x00', length: 8 - strlen(data)%8);

msg1  = smb2_header(command:3, status:STATUS_SUCCESS);
msg1 += null_signature;
msg1[20] = raw_string(0x40 + strlen(data));
msg1 += data;

# The second message in the compound request is compressed such that
#
#   (COMPRESSION_TRANSFORM_HEADER.offset +
#   COMPRESSION_TRANSFORM_HEADER.OriginalCompressedSegmentSize) > 0x800134
#
# Use QUERY_DIRECTORY so that the message is not subject to the 0x11000-byte
# max msg_size limit.
command = 0xE;
header = smb2_header(command:command, status:STATUS_SUCCESS);
header += null_signature;

uncompressed = msg1 + header;
cth = raw_dword(d:0x424D53FC)
  + raw_dword(d:orig_size)        # OriginalCompressedSegmentSize
  + raw_word(w:LZNT1)             # CompressionAlgorithm
  + raw_word(w:0)                 # flags
  + raw_dword(d:strlen(uncompressed)); # offset

packet = cth + uncompressed + compressed;

length = strlen(packet);
netbios = netbios_header (type:0, length:length) + packet;
send (socket:soc, data:netbios);
res = my_smb2_recv();
NetUseDel();

# The vulnerable server does not check
# offset + OriginalCompressedSegmentSize <= 0x800134, the compound request
# is processed and a compressed response is returned.
if((strlen(res) > 16 && get_dword(blob:res, pos:0) == 0x424D53FC)
  # Should not happen; but in case TREE_CONNECT in the compound request
  # fails, crash on vulnerable srv2.sys version < 10.0.18362.329
  || !smb_session_init(timeout:10))
{
  extra = 'Nessus was able to detect the vulnerability by sending a specially crafted message to the remote SMB server.';
  security_report_v4(
    port      : port,
    severity  : SECURITY_HOLE,
    extra     : extra
  );
}
# The patched server checks
# offset + OriginalCompressedSegmentSize <= 0x800134, and the check fails.
# The server closes the connection without returning a response.
else
  audit(AUDIT_HOST_NOT, 'affected');

VendorProductVersionCPE
microsoftwindowscpe:/o:microsoft:windows