Skip to main content
Glama
SlanyCukr

Bug Bounty MCP Server

by SlanyCukr

nikto_scan

Scan web servers for vulnerabilities by executing Nikto with configurable options for target, port, SSL, plugins, output format, and evasion techniques.

Instructions

Execute Nikto web server vulnerability scanner.

Args: target: Target hostname or IP address port: Port number to scan ssl: Use SSL/HTTPS plugins: Nikto plugins to run output_format: Output format (txt, xml, csv) evasion: Evasion techniques to use additional_args: Additional Nikto arguments

Returns: Web server vulnerability scan results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
additional_argsNo
evasionNo
output_formatNotxt
pluginsNo
portNo80
sslNo
targetYes

Implementation Reference

  • MCP registration and thin handler for 'nikto_scan' tool, proxies to REST API /api/nikto endpoint.
    def nikto_scan(
        target: str,
        port: str = "80",
        ssl: bool = False,
        plugins: str = "",
        output_format: str = "txt",
        evasion: str = "",
        additional_args: str = "",
    ) -> dict[str, Any]:
        """Execute Nikto web server vulnerability scanner.
    
        Args:
            target: Target hostname or IP address
            port: Port number to scan
            ssl: Use SSL/HTTPS
            plugins: Nikto plugins to run
            output_format: Output format (txt, xml, csv)
            evasion: Evasion techniques to use
            additional_args: Additional Nikto arguments
    
        Returns:
            Web server vulnerability scan results
        """
        data = {
            "target": target,
            "port": port,
            "ssl": ssl,
            "plugins": plugins,
            "output_format": output_format,
            "evasion": evasion,
            "additional_args": additional_args,
        }
    
        logger.info(f"๐Ÿ” Starting Nikto vulnerability scan on {target}")
        result = api_client.safe_post("api/nikto", data)
    
        if result.get("success"):
            logger.info(f"โœ… Nikto scan completed on {target}")
        else:
            logger.error("โŒ Nikto scan failed")
    
        return result
  • Core handler function for Nikto scan execution, registered via @tool() decorator, handles param extraction, command building, execution, and parsing.
    @tool()
    def execute_nikto():
        """Execute Nikto web server vulnerability scanner."""
        data = request.get_json()
        params = extract_nikto_params(data)
    
        logger.info(f"Executing Nikto scan on {params['target']}")
    
        started_at = datetime.now()
        command = build_nikto_command(params)
        execution_result = execute_command(command, params["timeout"])
        ended_at = datetime.now()
    
        return parse_nikto_output(execution_result, params, command, started_at, ended_at)
  • Helper function to extract and process input parameters for Nikto scan, including aggressive mode preset.
    def extract_nikto_params(data):
        """Extract nikto parameters from request data."""
        # Check for aggressive mode
        aggressive = data.get("aggressive", False)
    
        # Base parameters
        params = {
            "target": data["target"],
            "port": data.get("port", "80"),
            "ssl": data.get("ssl", False),
            "plugins": data.get("plugins", ""),
            "output_format": data.get("output_format", "txt"),
            "evasion": data.get("evasion", ""),
            "timeout": data.get("timeout", 600),
            "max_time": data.get("max_time", ""),
            "mutate": data.get("mutate", ""),
            "additional_args": data.get("additional_args", ""),
            # Authentication parameters
            "auth_type": data.get("auth_type", ""),  # basic, digest, ntlm
            "username": data.get("username", ""),
            "password": data.get("password", ""),
            # Custom headers
            "headers": data.get("headers", {}),  # Dict of header_name: header_value
            "user_agent": data.get("user_agent", ""),
            "cookies": data.get("cookies", ""),
            # Proxy settings
            "proxy": data.get("proxy", ""),
            # Other advanced options
            "virtual_host": data.get("virtual_host", ""),
            "config_file": data.get("config_file", ""),
        }
    
        # Apply aggressive preset if requested
        if aggressive:
            # Nikto aggressive preset
            params.update(
                {
                    "plugins": "@@ALL",
                    "timeout": 30,
                    "max_time": 3600,
                    "evasion": "1,2,3,4,5,6,7,8,9,A,B",
                    "mutate": "1,2,3,4,5,6",
                    "output_format": "json",
                }
            )
        return params
  • Helper function to construct the full Nikto CLI command from processed parameters.
    def build_nikto_command(params):
        """Build nikto command from parameters."""
        cmd_parts = ["nikto", "-h", params["target"]]
    
        if params["port"] and params["port"] != "80":
            cmd_parts.extend(["-p", str(params["port"])])
    
        if params["ssl"]:
            cmd_parts.append("-ssl")
    
        if params["plugins"]:
            cmd_parts.extend(["-Plugins", params["plugins"]])
    
        if params["output_format"] != "txt":
            cmd_parts.extend(["-Format", params["output_format"]])
    
        if params["evasion"]:
            cmd_parts.extend(["-evasion", params["evasion"]])
    
        if params["max_time"]:
            cmd_parts.extend(["-maxtime", str(params["max_time"])])
    
        if params["mutate"]:
            cmd_parts.extend(["-mutate", params["mutate"]])
    
        # Authentication support
        if params["auth_type"] and params["username"] and params["password"]:
            auth_string = f"{params['username']}:{params['password']}"
            if params["auth_type"].lower() == "basic":
                cmd_parts.extend(["-id", auth_string])
            elif params["auth_type"].lower() == "digest":
                # Nikto handles digest automatically when credentials are provided
                cmd_parts.extend(["-id", auth_string])
    
        # Custom headers support
        if params["headers"]:
            for header_name, header_value in params["headers"].items():
                cmd_parts.extend(["-header", f"{header_name}: {header_value}"])
    
        # User Agent
        if params["user_agent"]:
            cmd_parts.extend(["-useragent", params["user_agent"]])
    
        # Cookies
        if params["cookies"]:
            cmd_parts.extend(["-cookie", params["cookies"]])
    
        # Proxy support
        if params["proxy"]:
            cmd_parts.extend(["-useproxy", params["proxy"]])
    
        # Virtual host
        if params["virtual_host"]:
            cmd_parts.extend(["-vhost", params["virtual_host"]])
    
        # Config file
        if params["config_file"]:
            cmd_parts.extend(["-config", params["config_file"]])
    
        if params["additional_args"]:
            cmd_parts.extend(params["additional_args"].split())
    
        return " ".join(cmd_parts)
  • Helper function to parse Nikto command output and structure it into findings with metadata.
    def parse_nikto_output(execution_result, params, command, started_at, ended_at):
        """Parse nikto execution result and format response."""
        duration_ms = int((ended_at - started_at).total_seconds() * 1000)
    
        result = {
            "tool": "nikto",
            "target": params["target"],
            "params": params,
            "command": command,
            "started_at": started_at.isoformat(),
            "ended_at": ended_at.isoformat(),
            "duration_ms": duration_ms,
            "success": execution_result["success"],
            "raw_output": execution_result.get("stdout", ""),
            "error_output": execution_result.get("stderr", ""),
            "return_code": execution_result.get("return_code", -1),
            "findings": [],
            "stats": {"findings": 0, "dupes": 0, "payload_bytes": 0},
        }
    
        # Parse basic findings from output if successful
        if execution_result["success"] and result["raw_output"]:
            try:
                findings = []
                lines = result["raw_output"].strip().split("\n")
    
                for line in lines:
                    line = line.strip()
                    # Look for Nikto findings (lines that contain vulnerability indicators)
                    if any(
                        indicator in line.lower()
                        for indicator in [
                            "osvdb",
                            "cve",
                            "potential",
                            "vulnerability",
                            "misconfiguration",
                            "directory",
                            "file found",
                            "server version",
                        ]
                    ):
                        findings.append(
                            {
                                "type": "vulnerability",
                                "target": params["target"],
                                "evidence": {"raw_output": line},
                                "severity": "info",  # Direct mapping
                                "confidence": "medium",  # Direct mapping
                                "tags": ["nikto", "web-server"],
                                "raw_ref": line,
                            }
                        )
    
                result["findings"] = findings
                result["stats"]["findings"] = len(findings)
                result["stats"]["payload_bytes"] = len(result["raw_output"].encode("utf-8"))
            except Exception as e:
                logger.warning(f"Failed to parse Nikto findings: {e}")
    
        return result

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