feroxbuster_scan
Perform recursive directory scanning to discover hidden files and directories on web servers using brute-force wordlist attacks for security testing.
Instructions
Execute Feroxbuster for fast recursive directory scanning.
Args: url: Target URL wordlist: Wordlist file path threads: Number of concurrent threads depth: Maximum recursion depth extensions: File extensions to search for filter_codes: HTTP status codes to filter out timeout: Request timeout in seconds additional_args: Additional Feroxbuster arguments
Returns: Recursive directory discovery results
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| additional_args | No | ||
| depth | No | ||
| extensions | No | ||
| filter_codes | No | 404 | |
| threads | No | ||
| timeout | No | ||
| url | Yes | ||
| wordlist | No | /usr/share/wordlists/dirb/common.txt |
Implementation Reference
- src/mcp_server/app.py:639-684 (handler)MCP tool handler and registration for 'feroxbuster_scan'. This function defines the tool schema via arguments, registers it with FastMCP using @mcp.tool(), and proxies the execution to the REST API server endpoint /api/feroxbuster.@mcp.tool() def feroxbuster_scan( url: str, wordlist: str = "/usr/share/wordlists/dirb/common.txt", threads: int = 10, depth: int = 4, extensions: str = "", filter_codes: str = "404", timeout: int = 7, additional_args: str = "", ) -> dict[str, Any]: """Execute Feroxbuster for fast recursive directory scanning. Args: url: Target URL wordlist: Wordlist file path threads: Number of concurrent threads depth: Maximum recursion depth extensions: File extensions to search for filter_codes: HTTP status codes to filter out timeout: Request timeout in seconds additional_args: Additional Feroxbuster arguments Returns: Recursive directory discovery results """ data = { "url": url, "wordlist": wordlist, "threads": threads, "depth": depth, "extensions": extensions, "filter_codes": filter_codes, "timeout": timeout, "additional_args": additional_args, } logger.info(f"🔥 Starting Feroxbuster recursive scan on {url}") result = api_client.safe_post("api/feroxbuster", data) if result.get("success"): logger.info(f"✅ Feroxbuster scan completed on {url}") else: logger.error("❌ Feroxbuster scan failed") return result
- Backend REST API handler for the feroxbuster tool execution. Decorated with @tool decorator which likely registers the /api/feroxbuster route. Extracts parameters, builds CLI command, executes it, and parses JSON output into structured findings.@tool(required_fields=["url"]) def execute_feroxbuster(): """Execute Feroxbuster for fast directory scanning.""" data = request.get_json() params = extract_feroxbuster_params(data) logger.info(f"Executing Feroxbuster on {params['url']}") command = build_feroxbuster_command(params) execution_result = execute_command(command, timeout=1800) return parse_feroxbuster_result(execution_result)
- Helper function that constructs the feroxbuster CLI command string from input parameters, including quoting and conditional flags.def build_feroxbuster_command(params: dict) -> str: """Build feroxbuster command from parameters.""" cmd_parts = [ "feroxbuster", "-u", shlex.quote(params["url"]), "-w", shlex.quote(params["wordlist"]), ] cmd_parts.extend(["-t", str(params["threads"])]) cmd_parts.extend(["-d", str(params["depth"])]) cmd_parts.extend(["-T", str(params["timeout"])]) if params.get("rate_limit"): cmd_parts.extend(["-L", str(params["rate_limit"])]) if params["extensions"]: cmd_parts.extend(["-x", shlex.quote(params["extensions"])]) if params.get("status_codes"): cmd_parts.extend(["-s", shlex.quote(params["status_codes"])]) if params.get("filter_status"): cmd_parts.extend(["-C", shlex.quote(params["filter_status"])]) if params.get("auto_tune", False): cmd_parts.append("--auto-tune") if params.get("filter_size"): cmd_parts.extend(["-S", str(params["filter_size"])]) cmd_parts.append("--json") if params["additional_args"]: additional_parts = shlex.split(params["additional_args"]) cmd_parts.extend([shlex.quote(part) for part in additional_parts]) return " ".join(cmd_parts)
- Helper function that parses the JSON lines output from feroxbuster into standardized finding objects with evidence, severity, tags, etc.def parse_feroxbuster_json_output(stdout: str) -> list[dict[str, Any]]: """Parse feroxbuster JSON output into findings.""" findings = [] for line in stdout.split("\n"): if line.strip(): try: result_data = json.loads(line) if result_data.get("type") == "response": url = result_data.get("url", "") status_code = result_data.get("status", 0) content_length = result_data.get("content_length", 0) word_count = result_data.get("word_count", 0) line_count = result_data.get("line_count", 0) if url: parsed_url = urlparse(url) host = parsed_url.netloc path = parsed_url.path or "/" depth = len(url.rstrip("/").split("/")) - 3 if url else 0 severity = "info" confidence = "medium" tags = ["endpoint", "directory-enum"] if status_code: tags.append(f"status-{status_code}") if depth > 1: tags.append("deep-path") if parsed_url.scheme == "https": tags.append("https") else: tags.append("http") finding = create_finding( finding_type="endpoint", target=host, evidence={ "url": url, "path": path, "status_code": status_code, "content_length": content_length, "word_count": word_count, "line_count": line_count, "depth": depth, "scheme": parsed_url.scheme, "port": parsed_url.port, "discovered_by": "feroxbuster", }, severity=severity, confidence=confidence, tags=tags, raw_ref=line, ) findings.append(finding) except json.JSONDecodeError: continue if len(findings) > 100: findings = findings[:100] return findings