Skip to main content
Glama
x0base

mcp-security-toolkit

phpggc_generate

Create PHP unserialize gadget chains for security assessments. Specify a chain identifier and shell command; output raw or encoded payloads.

Instructions

Generate a single PHP unserialize gadget chain via phpggc.

Args: chain: Gadget chain identifier (e.g. Laravel/RCE9, Symfony/RCE4, Monolog/RCE1). Run phpggc -l locally to enumerate. command: Shell command to embed in the chain (e.g. id, curl ...). encoding: One of raw, base64, url, json, soft. fast_destruct: Adds --fast-destruct (triggers without await). extra_args: Extra raw arguments to pass through.

Returns: PhpggcReport with the generated payload (string). If phpggc is not installed, available is False.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chainYes
commandYes
encodingNobase64
fast_destructNo
extra_argsNo

Implementation Reference

  • The main handler function `phpggc_generate` that wraps the phpggc CLI to generate PHP deserialization gadget chains. It checks opt-in env var, validates inputs (chain, command, encoding), locates the phpggc binary, constructs CLI args, runs subprocess, and returns a PhpggcReport dict.
    def phpggc_generate(
        chain: str,
        command: str,
        encoding: Literal["raw", "base64", "url", "json", "soft"] = "base64",
        fast_destruct: bool = False,
        extra_args: list[str] | None = None,
    ) -> dict:
        """Generate a single PHP unserialize gadget chain via `phpggc`.
    
        Args:
            chain: Gadget chain identifier (e.g. `Laravel/RCE9`, `Symfony/RCE4`,
                `Monolog/RCE1`). Run `phpggc -l` locally to enumerate.
            command: Shell command to embed in the chain (e.g. `id`, `curl ...`).
            encoding: One of `raw`, `base64`, `url`, `json`, `soft`.
            fast_destruct: Adds `--fast-destruct` (triggers without await).
            extra_args: Extra raw arguments to pass through.
    
        Returns:
            PhpggcReport with the generated payload (string). If `phpggc` is not
            installed, `available` is False.
        """
        if os.environ.get(OPT_IN_ENV, "").lower() not in {"1", "true", "yes"}:
            return {
                "error": "offensive-tool-disabled",
                "hint": (
                    f"This tool generates PHP deserialization payloads and is "
                    f"disabled by default. Set {OPT_IN_ENV}=1 in the MCP server's "
                    f"environment to enable. Only use against systems you are "
                    f"explicitly authorized to test."
                ),
            }
    
        if not isinstance(chain, str) or not chain.strip():
            return {"error": "chain must be a non-empty string"}
        if not isinstance(command, str) or not command.strip():
            return {"error": "command must be a non-empty string"}
        if encoding not in ENCODINGS:
            return {"error": f"encoding must be one of {ENCODINGS}"}
    
        bin_path = shutil.which("phpggc")
        if not bin_path:
            return PhpggcReport(
                available=False, chain=chain, encoding=encoding,
                stderr="phpggc binary not found on PATH — install from https://github.com/ambionics/phpggc",
            ).model_dump()
    
        args: list[str] = [bin_path]
        if encoding == "base64":
            args.append("-b")
        elif encoding == "url":
            args.append("-u")
        elif encoding == "json":
            args.append("-j")
        elif encoding == "soft":
            args.append("-s")
        # encoding == "raw" → no flag
        if fast_destruct:
            args.append("--fast-destruct")
        if extra_args:
            args.extend(str(a) for a in extra_args)
        # `--` separates flags from positional args: prevents a `chain` value
        # starting with `-` from being reinterpreted as a phpggc flag.
        args.append("--")
        args.extend([chain, command])
    
        try:
            result = subprocess.run(
                args, capture_output=True, text=True, timeout=30, check=False,
            )
        except (subprocess.TimeoutExpired, OSError) as e:
            return PhpggcReport(
                available=True, chain=chain, encoding=encoding,
                stderr=f"phpggc execution failed: {e}", cmd=args,
            ).model_dump()
    
        if result.returncode != 0:
            return PhpggcReport(
                available=True, chain=chain, encoding=encoding,
                stderr=result.stderr.strip() or "non-zero exit", cmd=args,
            ).model_dump()
    
        return PhpggcReport(
            available=True, chain=chain, encoding=encoding,
            payload=result.stdout.strip(), cmd=args,
        ).model_dump()
  • PhpggcReport Pydantic BaseModel schema defining the output structure: available (bool), chain, encoding, payload, stderr, cmd.
    class PhpggcReport(BaseModel):
        available: bool
        chain: str | None
        encoding: str
        payload: str | None = None
        stderr: str | None = None
        cmd: list[str] = []
  • Registration of the phpggc_generate tool with the MCP server via `mcp.tool()(phpggc_generate.phpggc_generate)`.
    mcp.tool()(phpggc_generate.phpggc_generate)
  • OPT_IN_ENV constant ('MCP_SECURITY_TOOLKIT_ENABLE_OFFENSIVE') used as an opt-in gate for this offensive tool.
    OPT_IN_ENV = "MCP_SECURITY_TOOLKIT_ENABLE_OFFENSIVE"
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description shoulders the burden. It explains the return status when phpggc is missing and lists all parameters including fast_destruct behavior. However, it omits error handling details for invalid chains or commands.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: a one-line summary followed by an Args list and Returns section. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 5 parameters, no output schema, and no annotations, the description covers purpose, all parameters, and the return value (PhpggcReport). It also addresses the installation dependency. No significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description thoroughly explains each parameter with examples (chain identifiers, command types, encoding options, fast_destruct flag, extra_args). This fully compensates for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Generate a single PHP unserialize gadget chain via phpggc' with a specific verb and resource. It is distinct from sibling tools like risk audit or creds lookup, so no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for generating PHP gadget chains but lacks explicit when-to-use versus alternatives. It provides a tip to enumerate chains locally but no clear guidance on prerequisites or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/x0base/mcp-security-toolkit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server