Lucene search

K
openvasCopyright (C) 2019 Greenbone AGOPENVAS:1361412562310108611
HistoryJul 05, 2019 - 12:00 a.m.

Microsoft Windows Remote Desktop Services 'CVE-2019-0708' Remote Code Execution Vulnerability (BlueKeep) - (Remote Active)

2019-07-0500:00:00
Copyright (C) 2019 Greenbone AG
plugins.openvas.org
819

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.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

AI Score

Confidence

High

10 High

CVSS2

Access Vector

NETWORK

Access 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

0.975 High

EPSS

Percentile

100.0%

Microsoft Windows Remote Desktop Services is prone to the remote code execution vulnerability known as

# SPDX-FileCopyrightText: 2019 Greenbone AG
# Some text descriptions might be excerpted from (a) referenced
# source(s), and are Copyright (C) by the respective right holder(s).
#
# SPDX-License-Identifier: GPL-2.0-or-later

if(description)
{
  script_oid("1.3.6.1.4.1.25623.1.0.108611");
  script_version("2023-04-18T10:19:20+0000");
  script_xref(name:"CISA", value:"Known Exploited Vulnerability (KEV) catalog");
  script_xref(name:"URL", value:"https://www.cisa.gov/known-exploited-vulnerabilities-catalog");
  script_cve_id("CVE-2019-0708");
  script_tag(name:"last_modification", value:"2023-04-18 10:19:20 +0000 (Tue, 18 Apr 2023)");
  script_tag(name:"creation_date", value:"2019-07-05 11:44:28 +0000 (Fri, 05 Jul 2019)");
  script_tag(name:"cvss_base", value:"10.0");
  script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:C/I:C/A:C");
  script_tag(name:"severity_vector", value:"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");
  script_tag(name:"severity_origin", value:"NVD");
  script_tag(name:"severity_date", value:"2021-06-03 18:15:00 +0000 (Thu, 03 Jun 2021)");
  script_name("Microsoft Windows Remote Desktop Services 'CVE-2019-0708' Remote Code Execution Vulnerability (BlueKeep) - (Remote Active)");
  script_category(ACT_ATTACK);
  script_copyright("Copyright (C) 2019 Greenbone AG");
  script_family("Windows : Microsoft Bulletins");
  script_dependencies("ms_rdp_detect.nasl");
  script_require_ports("Services/ms-wbt-server", 3389);
  script_mandatory_keys("msrdp/detected");

  script_xref(name:"URL", value:"https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708");
  script_xref(name:"URL", value:"https://support.microsoft.com/help/4499164");
  script_xref(name:"URL", value:"https://support.microsoft.com/help/4499175");
  script_xref(name:"URL", value:"https://support.microsoft.com/help/4499149");
  script_xref(name:"URL", value:"https://support.microsoft.com/help/4499180");
  script_xref(name:"URL", value:"https://support.microsoft.com/help/4500331");
  script_xref(name:"URL", value:"https://blogs.technet.microsoft.com/msrc/2019/05/14/prevent-a-worm-by-updating-remote-desktop-services-cve-2019-0708/");
  script_xref(name:"URL", value:"https://support.microsoft.com/en-us/help/4500705/customer-guidance-for-cve-2019-0708");
  script_xref(name:"URL", value:"https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc732713(v=ws.11)");
  script_xref(name:"URL", value:"http://www.securityfocus.com/bid/108273");
  script_xref(name:"URL", value:"http://packetstormsecurity.com/files/153133/Microsoft-Windows-Remote-Desktop-BlueKeep-Denial-Of-Service.html");
  script_xref(name:"URL", value:"https://www.malwaretech.com/2019/05/analysis-of-cve-2019-0708-bluekeep.html");
  script_xref(name:"URL", value:"https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/rdp-stands-for-really-do-patch-understanding-the-wormable-rdp-vulnerability-cve-2019-0708");

  script_tag(name:"summary", value:"Microsoft Windows Remote Desktop Services is prone to the remote code execution vulnerability known as 'BlueKeep'.");

  script_tag(name:"vuldetect", value:"Sends a specially crafted request to the target systems
  Remote Desktop Service via RDP and checks the response.");

  script_tag(name:"insight", value:"A remote code execution vulnerability exists in Remote Desktop Services
  when an unauthenticated attacker connects to the target system using RDP and sends specially crafted requests.
  This vulnerability is pre-authentication and requires no user interaction.

  For an in-depth analysis and further technical insights and details please see the references.");

  script_tag(name:"impact", value:"Successful exploitation would allow an attacker to execute arbitrary code on the target system.
  An attacker could then install programs, view, change, or delete data, or create new accounts with full user rights.");

  script_tag(name:"affected", value:"- Microsoft Windows 7

  - Microsoft Windows Server 2008 R2

  - Microsoft Windows Server 2008

  - Microsoft Windows Server 2003 R2

  - Microsoft Windows Server 2003

  - Microsoft Windows Vista and Microsoft Windows XP (including Embedded)");

  script_tag(name:"solution", value:"The vendor has released updates. Please see
  the references for more information.

  As a workaround enable Network Level Authentication (NLA) on systems running supported
  editions of Windows 7, Windows Server 2008, and Windows Server 2008 R2.

  NOTE: After enabling NLA affected systems are still vulnerable to Remote Code Execution (RCE)
  exploitation if the attacker has valid credentials that can be used to successfully authenticate.");

  script_tag(name:"qod_type", value:"remote_vul");
  script_tag(name:"solution_type", value:"VendorFix");

  exit(0);
}

include("rdp.inc");
include("misc_func.inc");
include("port_service_func.inc");
include("dump.inc");
include("byte_func.inc");
include("http_func.inc");
include("bin.inc");

# nb: Available since r25570 of libs 9.0
if( ! defined_func( "rsa_public_encrypt" ) )
  exit( 0 );

port = service_get_port( default:3389, proto:"ms-wbt-server" );

if( get_kb_item( "rdp/" + port + "/isxrdp" ) )
  exit( 0 );

if( ! soc = open_sock_tcp( port, transport:ENCAPS_IP ) ) # nb: Currently don't get a response back after sending the rdp_create_pdu_negotiation_request() request if SSL/TLS is used
  exit( 0 );

req = rdp_create_pdu_negotiation_request( use_cookie:TRUE );
res = rdp_send_recv( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_negotiation_request()" );
len = strlen( res );

# nb: Length depends on if a mstshash Cookie was passed.
# Without a cookie length is 11
# With a cookie the length might be 11 or 19
# see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/13757f8f-66db-4273-9d2c-385c33b1e483
if( ! res || ( len != 11 && len != 19 ) || hexstr( res ) !~ "^030000" ) {
  close( soc );
  exit( 0 );
}

req = rdp_create_pdu_connect_initial_request();
res = rdp_send_recv( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_connect_initial_request()" );
if( ! res ) {
  close( soc );
  exit( 0 );
}

srv_data = rdp_parse_serverdata( data:res, debug:FALSE );
if( ! srv_data ) {
  close( soc );
  exit( 0 );
}

req = rdp_create_pdu_erect_domain_request();
rdp_send( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_erect_domain_request()" );

req = rdp_create_pdu_attach_user_request();
res = rdp_send_recv( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_attach_user_request()" );
if( ! res || strlen( res ) < 11 ) {
  close( soc );
  exit( 0 );
}

user1 = substr(res, 9, 11);

foreach id( make_list( 1009, 1003, 1004, 1005, 1006, 1007, 1008 ) ) {
  req = rdp_create_pdu_channel_request( user1:user1, channel_id:id, debug:FALSE );
  rdp_send_recv( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_channel_request()" );
}

client_rand = rdp_create_client_random();

req = rdp_create_pdu_security_exchange( client_rand:client_rand,
                                        public_exponent:srv_data["public_exponent"],
                                        modulus:srv_data["modulus"],
                                        bitlen:srv_data["bitlen"] );
rdp_send( socket:soc, data:req, debug:FALSE, debug_req_name:"rdp_create_pdu_security_exchange()" );

client_info_pkt = rdp_create_pdu_client_info_request();

rc4_keys = rdp_calculate_rc4_keys( client_rand:client_rand, server_rand:srv_data["server_random"], debug:FALSE );

client_confirm_active = rdp_create_pdu_client_confirm_active_request();

sync = rdp_create_pdu_client_synchronize_request( target_user:1009 );

coop = rdp_build_pdu_client_control_cooperate();

client_req_control = rdp_create_pdu_client_control_request();

event_sync = rdp_create_pdu_client_input_event_sychronize_request();

font_list = rdp_create_pdu_client_font_list_request();

# 0x03 = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST
x86_payload = rdp_build_virtual_channel_pdu_request( flags:0x03, data:raw_string( 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) );
x64_payload = rdp_build_virtual_channel_pdu_request( flags:0x03, data:raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) );

# the whole static data which has to be encrypted
full_data = client_info_pkt + client_confirm_active + sync + coop + client_req_control + event_sync + font_list;
for( i = 0; i <= 5; i++ ) {
  full_data += x86_payload;
  full_data += x64_payload;
}

enc_data = rc4_encrypt( key:rc4_keys["initial_client_encryptkey_128"], data:full_data );

# Dissect the encrypted data again
# TODO: NASL rc4_encrypt currently can't encrypt the data for our purposes so
# the data needs to be dissected here (see comment in rdp_build_pkt() as well).
start = 0;
end = strlen( client_info_pkt ) - 1;
enc_client_info_pkt = substr( enc_data, start, end );
enc_client_info_pkt = rdp_build_pkt( data:client_info_pkt, client_info:TRUE, rdp_sec:TRUE, enc_data:enc_client_info_pkt, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( client_confirm_active ) - 1;
enc_client_confirm_active = substr( enc_data, start, end );
enc_client_confirm_active = rdp_build_pkt( data:client_confirm_active, rdp_sec:TRUE, enc_data:enc_client_confirm_active, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( sync ) - 1;
enc_sync = substr( enc_data, start, end );
enc_sync = rdp_build_pkt( data:sync, rdp_sec:TRUE, enc_data:enc_sync, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( coop ) - 1;
enc_coop = substr( enc_data, start, end );
enc_coop = rdp_build_pkt( data:coop, rdp_sec:TRUE, enc_data:enc_coop, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( client_req_control ) - 1;
enc_client_req_control = substr( enc_data, start, end );
enc_client_req_control = rdp_build_pkt( data:client_req_control, rdp_sec:TRUE, enc_data:enc_client_req_control, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( event_sync ) - 1;
enc_event_sync = substr( enc_data, start, end );
enc_event_sync = rdp_build_pkt( data:event_sync, rdp_sec:TRUE, enc_data:enc_event_sync, hmackey:rc4_keys["mac_key"] );

start = end + 1;
end = start + strlen( font_list ) - 1;
enc_font_list = substr( enc_data, start, end );
enc_font_list = rdp_build_pkt( data:font_list, rdp_sec:TRUE, enc_data:enc_font_list, hmackey:rc4_keys["mac_key"] );

enc_x86_payload_list = make_list();
enc_x64_payload_list = make_list();

for (i=0; i<=5; i++) {
  start = end + 1;
  end = start + strlen( x86_payload ) - 1;
  enc_x86_payload = substr( enc_data, start, end );
  # 0xed03 = Channel 1005
  enc_x86_payload = rdp_build_pkt( data:x86_payload, rdp_sec:TRUE, channel_id:raw_string( 0x03, 0xed ), enc_data:enc_x86_payload, hmackey:rc4_keys["mac_key"] );
  enc_x86_payload_list[i] = enc_x86_payload;

  start = end + 1;
  end = start + strlen( x64_payload ) - 1;
  enc_x64_payload = substr( enc_data, start, end );
  # 0xed03 = Channel 1005
  enc_x64_payload = rdp_build_pkt( data:x64_payload, rdp_sec:TRUE, channel_id:raw_string( 0x03, 0xed ), enc_data:enc_x64_payload, hmackey:rc4_keys["mac_key"] );
  enc_x64_payload_list[i] = enc_x64_payload;
}

res = rdp_send_recv( socket:soc, data:enc_client_info_pkt, debug:FALSE, debug_req_name:"rdp_create_pdu_client_info_request() / License packet" );
# nb: Windows XP sometimes sends a very large license packet. This is likely
# some form of license error. When it does this it doesn't send a Server
# Demand packet. If we wait on one we will time out here and error. We
# can still successfully check for vulnerability anyway.
if( ! res || strlen( res ) <= 34 )
  rdp_recv( socket:soc, debug:FALSE, debug_req_name:"Server Demand packet" );

# nb: Keep the code here as is and don't raise the received length or e.g. use rdp_send_recv(). For some unknown reason trying
# to change such things will cause a false negative against Windows XP systems.
rdp_send( socket:soc, data:enc_client_confirm_active, debug:FALSE, debug_req_name:"rdp_create_pdu_client_confirm_active_request()" );

rdp_send( socket:soc, data:enc_sync + enc_coop, debug:FALSE, debug_req_name:"rdp_create_pdu_client_synchronize_request() and rdp_build_pdu_client_control_cooperate()" );

rdp_send( socket:soc, data:enc_client_req_control, debug:FALSE, debug_req_name:"rdp_create_pdu_client_control_request()" );

rdp_send( socket:soc, data:enc_event_sync, debug:FALSE, debug_req_name:"rdp_create_pdu_client_input_event_sychronize_request()" );

rdp_send( socket:soc, data:enc_font_list, debug:FALSE, debug_req_name:"rdp_create_pdu_client_font_list_request()" );

# nb: Receive all data / clear the socket before sending the payloads below.
for( i = 0; i <= 5; i++ ) {
  _res = rdp_recv( socket:soc );
  if( ! _res )
    recv( socket:soc, length:1024, min:1 );
}

report = "By sending a crafted request the RDP service answered with a 'MCS Disconnect Provider Ultimatum PDU - 2.2.2.3' response which indicates that a RCE attack can be executed.";

for( i = 0; i <= 5; i++ ) {

  rdp_send( socket:soc, data:enc_x86_payload_list[i], debug:FALSE, debug_req_name:"x86 payload of rdp_build_virtual_channel_pdu_request()" );
  rdp_send( socket:soc, data:enc_x64_payload_list[i], debug:FALSE, debug_req_name:"x64 payload of rdp_build_virtual_channel_pdu_request()" );

  # nb: Don't use rdp_recv() as it might not receive all data due to unexpected RDP packages
  # received where the length calculation from the header doesn't work as expected.
  res = recv( socket:soc, length:2048, min:1 );
  if( res && hexstr( res ) =~ "^0300000902f0802180$" ) {
    close( soc );
    security_message( port:port, data:report );
    exit( 0 );
  }

  for( j = 0; j<= 3; j++ ) {
    res = recv( socket:soc, length:2048, min:1 );
    if( res && hexstr( res ) =~ "^0300000902f0802180$" ) {
      close( soc );
      security_message( port:port, data:report );
      exit( 0 );
    }
  }
}

close( soc );
exit( 0 );

References

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.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

AI Score

Confidence

High

10 High

CVSS2

Access Vector

NETWORK

Access 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

0.975 High

EPSS

Percentile

100.0%