Skip to main content
Glama
SlanyCukr

Bug Bounty MCP Server

by SlanyCukr

wfuzz_scan

Execute web application fuzzing to discover hidden directories, files, and parameters by testing various inputs against target URLs.

Instructions

Execute Wfuzz for web application fuzzing.

Args: url: Target URL with FUZZ keyword wordlist: Wordlist file path fuzz_parameter: Parameter to fuzz (default: FUZZ) hide_codes: HTTP status codes to hide threads: Number of concurrent threads follow_redirects: Follow HTTP redirects additional_args: Additional Wfuzz arguments

Returns: Web application fuzzing results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
additional_argsNo
follow_redirectsNo
fuzz_parameterNoFUZZ
hide_codesNo404
threadsNo
urlYes
wordlistNo/usr/share/wordlists/dirb/common.txt

Implementation Reference

  • Primary handler implementing the wfuzz tool logic: extracts parameters, builds command, executes wfuzz, parses output.
    @tool(required_fields=["url"])
    def execute_wfuzz():
        """Execute Wfuzz for web application fuzzing."""
        data = request.get_json()
        params = extract_wfuzz_params(data)
    
        logger.info(f"Executing Wfuzz on {params['url']}")
    
        started_at = datetime.now()
        command = build_wfuzz_command(params)
        logger.info(f"Wfuzz command: {command}")
    
        execution_result = execute_command(command, timeout=params["timeout"])
        ended_at = datetime.now()
    
        return parse_wfuzz_result(execution_result, params, command, started_at, ended_at)
  • MCP server registration of the 'wfuzz_scan' tool, defining input schema via parameters and proxying to REST API /api/wfuzz.
    @mcp.tool()
    def wfuzz_scan(
        url: str,
        wordlist: str = "/usr/share/wordlists/dirb/common.txt",
        fuzz_parameter: str = "FUZZ",
        hide_codes: str = "404",
        threads: int = 10,
        follow_redirects: bool = False,
        additional_args: str = "",
    ) -> dict[str, Any]:
        """Execute Wfuzz for web application fuzzing.
    
        Args:
            url: Target URL with FUZZ keyword
            wordlist: Wordlist file path
            fuzz_parameter: Parameter to fuzz (default: FUZZ)
            hide_codes: HTTP status codes to hide
            threads: Number of concurrent threads
            follow_redirects: Follow HTTP redirects
            additional_args: Additional Wfuzz arguments
    
        Returns:
            Web application fuzzing results
        """
        data = {
            "url": url,
            "wordlist": wordlist,
            "fuzz_parameter": fuzz_parameter,
            "hide_codes": hide_codes,
            "threads": threads,
            "follow_redirects": follow_redirects,
            "additional_args": additional_args,
        }
    
        logger.info(f"🎯 Starting Wfuzz scan on {url}")
        result = api_client.safe_post("api/wfuzz", data)
    
        if result.get("success"):
            logger.info(f"✅ Wfuzz scan completed on {url}")
        else:
            logger.error("❌ Wfuzz scan failed")
    
        return result
  • Helper to extract and normalize wfuzz parameters from input data, with aggressive mode support.
    def extract_wfuzz_params(data: dict) -> dict:
        """Extract wfuzz parameters from request data."""
        aggressive = data.get("aggressive", False)
    
        base_params = {
            "url": data.get("url", data.get("domain", "")),
            "wordlist": data.get(
                "wordlist", "/usr/share/wordlists/wfuzz/Injections/All-attack.txt"
            ),
            "threads": data.get("threads", 40),
            "hide_codes": data.get("hide_codes", "404"),
            "show_codes": data.get("show_codes", "200,301,302,401,403,500"),
            "follow_redirects": data.get("follow_redirects", False),
            "payload": data.get("payload", "FUZZ"),
            "timeout": data.get("timeout", 300),
            "additional_args": data.get("additional_args", ""),
        }
    
        if aggressive:
            base_params.update(
                {
                    "threads": 100,
                    "hide_codes": "404",
                    "show_codes": "200,301,302,401,403,500",
                    "timeout": 30,
                }
            )
    
        return base_params
  • Helper to construct the full wfuzz command line from parameters.
    def build_wfuzz_command(params: dict) -> str:
        """Build wfuzz command from parameters."""
        command_parts = ["wfuzz", "-w", params["wordlist"], "-t", str(params["threads"])]
    
        if params["hide_codes"]:
            command_parts.extend(["--hc", params["hide_codes"]])
    
        if params["show_codes"]:
            command_parts.extend(["--sc", params["show_codes"]])
    
        if params["follow_redirects"]:
            command_parts.append("-L")
    
        # Handle FUZZ parameter in URL
        url = params["url"]
        if params["payload"] not in url:
            if url.endswith("/"):
                url += params["payload"]
            else:
                url += f"/{params['payload']}"
        command_parts.append(url)
    
        if params["additional_args"]:
            command_parts.extend(params["additional_args"].split())
    
        return " ".join(command_parts)
  • Helper to parse wfuzz execution results into structured findings with stats and execution details.
    def parse_wfuzz_result(
        execution_result: dict,
        params: dict,
        command: str,
        started_at: datetime,
        ended_at: datetime,
    ) -> dict[str, Any]:
        """Parse wfuzz execution result and format response."""
        duration_ms = int((ended_at - started_at).total_seconds() * 1000)
    
        if not execution_result["success"]:
            return {
                "success": False,
                "tool": "wfuzz",
                "params": params,
                "started_at": started_at.isoformat(),
                "ended_at": ended_at.isoformat(),
                "duration_ms": duration_ms,
                "error": execution_result.get("stderr", "Command execution failed"),
                "findings": [],
                "stats": {"findings": 0, "dupes": 0, "payload_bytes": 0},
            }
    
        stdout = execution_result.get("stdout", "")
        findings = parse_wfuzz_output(stdout)
        payload_bytes = len(stdout.encode("utf-8"))
    
        return {
            "success": True,
            "tool": "wfuzz",
            "target": params["url"],
            "command": command,
            "parameters": params,
            "started_at": started_at.isoformat(),
            "ended_at": ended_at.isoformat(),
            "duration_ms": duration_ms,
            "findings": findings,
            "stats": {
                "findings": len(findings),
                "dupes": 0,
                "payload_bytes": payload_bytes,
            },
            "execution": {
                "success": execution_result["success"],
                "return_code": execution_result["return_code"],
                "stdout": execution_result["stdout"],
                "stderr": execution_result["stderr"],
            },
        }

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/SlanyCukr/bugbounty-mcp-server'

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