nikto_scan.py•3.36 kB
"""
Nikto Web Vulnerability Scanner Tool
Comprehensive web application vulnerability scanning
"""
from typing import Dict, Any, List
from .base_tool import BaseTool
import subprocess
class NiktoScanTool(BaseTool):
"""Nikto web vulnerability scanner tool"""
def __init__(self):
super().__init__()
self.name = "nikto_scan"
self.description = "Comprehensive web application vulnerability scanning using Nikto. Scans for common web vulnerabilities, misconfigurations, and security issues."
def get_tool_definition(self) -> Dict[str, Any]:
"""Return MCP-compatible tool definition"""
return {
"name": self.name,
"description": self.description,
"inputSchema": {
"type": "object",
"properties": {
"target": {
"type": "string",
"description": "Target URL or domain to scan (e.g., example.com or https://example.com)"
},
"port": {
"type": "integer",
"description": "Port number (default: 80 for http, 443 for https)",
"default": 80
}
},
"required": ["target"]
}
}
async def execute(self, arguments: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Execute Nikto scan"""
try:
target = arguments.get("target", "")
port = arguments.get("port")
if not target:
return self.format_error("Target is required")
# Remove protocol if present
target = target.replace("https://", "").replace("http://", "").split("/")[0]
# Auto-detect port if not specified
if port is None:
port = 443 if "https" in arguments.get("target", "") else 80
# Build Nikto command
cmd = f"nikto -h {target} -p {port} -Tuning 123456789ab -Format txt"
try:
result = subprocess.run(
["wsl", "bash", "-c", cmd],
capture_output=True,
text=True,
timeout=600 # 10 minutes
)
except FileNotFoundError:
result = subprocess.run(
["bash", "-c", cmd],
capture_output=True,
text=True,
timeout=600
)
if result.returncode == 0 or result.stdout: # Nikto may return non-zero even on success
output = result.stdout if result.stdout else "Scan completed"
formatted = f"✅ Nikto Scan Results for {target}:{port}\n{'='*60}\n{output}\n{'='*60}"
return self.format_success(formatted)
else:
error = result.stderr or "Scan failed"
return self.format_error(f"Nikto scan failed: {error}")
except subprocess.TimeoutExpired:
return self.format_error("Scan timeout (exceeded 10 minutes)")
except Exception as e:
return self.format_error(f"Execution failed: {str(e)}")
tool_instance = NiktoScanTool()