Skip to main content
Glama

MCP Pentest

workflow.ts•21 kB
import { ReconTools, ScanResult, PortScanResult, TechDetectionResult } from '../tools/recon.js'; import { VulnScanTools, VulnerabilityResult } from '../tools/vulnscan.js'; import { ExploitTools, ExploitResult } from '../tools/exploit.js'; export interface PentestWorkflow { target: string; scope: 'network' | 'web' | 'full'; intensity: 'passive' | 'active' | 'aggressive'; phases: WorkflowPhase[]; current_phase: number; results: WorkflowResults; recommendations: string[]; } export interface WorkflowPhase { name: string; description: string; status: 'pending' | 'running' | 'completed' | 'failed' | 'skipped'; tools: string[]; results?: ScanResult[]; duration?: number; start_time?: string; end_time?: string; } export interface WorkflowResults { reconnaissance: { open_ports: PortScanResult[]; technologies: TechDetectionResult[]; subdomains: string[]; directories: string[]; }; vulnerabilities: VulnerabilityResult[]; exploits: ExploitResult[]; risk_score: number; threat_level: 'low' | 'medium' | 'high' | 'critical'; } export interface NextStepsRecommendation { priority: 'high' | 'medium' | 'low'; action: string; tool: string; reason: string; estimated_time: string; risk_level: 'low' | 'medium' | 'high' | 'critical'; } export class WorkflowEngine { private reconTools: ReconTools; private vulnScanTools: VulnScanTools; private exploitTools: ExploitTools; constructor() { this.reconTools = new ReconTools(); this.vulnScanTools = new VulnScanTools(); this.exploitTools = new ExploitTools(); } async autoPentest(target: string, scope: 'network' | 'web' | 'full' = 'full', intensity: 'passive' | 'active' | 'aggressive' = 'active'): Promise<ScanResult> { try { const workflow: PentestWorkflow = this.initializeWorkflow(target, scope, intensity); console.error(`Starting automated pentest for ${target} (scope: ${scope}, intensity: ${intensity})`); // Execute phases sequentially for (let i = 0; i < workflow.phases.length; i++) { workflow.current_phase = i; const phase = workflow.phases[i]; console.error(`Executing phase: ${phase.name}`); phase.status = 'running'; phase.start_time = new Date().toISOString(); try { await this.executePhase(workflow, phase); phase.status = 'completed'; phase.end_time = new Date().toISOString(); // Analyze results and decide next steps await this.analyzePhaseResults(workflow, phase); } catch (error) { phase.status = 'failed'; console.error(`Phase ${phase.name} failed:`, error); // Decide whether to continue or abort based on failure if (this.shouldAbortOnFailure(phase, error)) { break; } } } // Calculate final risk score and recommendations this.calculateFinalRiskScore(workflow); this.generateFinalRecommendations(workflow); return { target, timestamp: new Date().toISOString(), tool: 'auto_pentest', results: { workflow, completed_phases: workflow.phases.filter(p => p.status === 'completed').length, total_phases: workflow.phases.length, final_risk_score: workflow.results.risk_score, threat_level: workflow.results.threat_level }, status: 'success' }; } catch (error) { return { target, timestamp: new Date().toISOString(), tool: 'auto_pentest', results: {}, status: 'error', error: error instanceof Error ? error.message : String(error) }; } } async suggestNextSteps(scanResults: string): Promise<ScanResult> { try { const results = JSON.parse(scanResults); const recommendations: NextStepsRecommendation[] = []; // Analyze reconnaissance results if (results.reconnaissance) { recommendations.push(...this.analyzeReconResults(results.reconnaissance)); } // Analyze vulnerability results if (results.vulnerabilities) { recommendations.push(...this.analyzeVulnResults(results.vulnerabilities)); } // Analyze exploitation results if (results.exploits) { recommendations.push(...this.analyzeExploitResults(results.exploits)); } // Sort recommendations by priority and risk recommendations.sort((a, b) => { const priorityOrder = { high: 3, medium: 2, low: 1 }; const riskOrder = { critical: 4, high: 3, medium: 2, low: 1 }; const aScore = priorityOrder[a.priority] + riskOrder[a.risk_level]; const bScore = priorityOrder[b.priority] + riskOrder[b.risk_level]; return bScore - aScore; }); return { target: 'analysis', timestamp: new Date().toISOString(), tool: 'suggest_next_steps', results: { recommendations: recommendations.slice(0, 10), // Top 10 recommendations total_recommendations: recommendations.length, analysis_summary: this.generateAnalysisSummary(results) }, status: 'success' }; } catch (error) { return { target: 'analysis', timestamp: new Date().toISOString(), tool: 'suggest_next_steps', results: {}, status: 'error', error: error instanceof Error ? error.message : String(error) }; } } // Helper methods private initializeWorkflow(target: string, scope: string, intensity: string): PentestWorkflow { const phases: WorkflowPhase[] = []; // Always start with reconnaissance phases.push({ name: 'reconnaissance', description: 'Information gathering and target enumeration', status: 'pending', tools: ['nmap_scan', 'subdomain_enum', 'tech_detection'] }); if (scope === 'web' || scope === 'full') { phases.push({ name: 'web_discovery', description: 'Web application discovery and enumeration', status: 'pending', tools: ['directory_bruteforce', 'tech_detection'] }); phases.push({ name: 'web_vulnerability_scan', description: 'Web application vulnerability assessment', status: 'pending', tools: ['nuclei_scan', 'nikto_scan', 'custom_web_vuln_scan'] }); } if (scope === 'network' || scope === 'full') { phases.push({ name: 'network_vulnerability_scan', description: 'Network service vulnerability assessment', status: 'pending', tools: ['nuclei_scan', 'service_specific_scans'] }); } if (intensity === 'active' || intensity === 'aggressive') { phases.push({ name: 'exploitation', description: 'Controlled exploitation attempts', status: 'pending', tools: ['exploit_attempt', 'metasploit_search'] }); } phases.push({ name: 'post_exploitation', description: 'Post-exploitation analysis and privilege escalation', status: 'pending', tools: ['privilege_escalation', 'lateral_movement'] }); return { target, scope: scope as any, intensity: intensity as any, phases, current_phase: 0, results: { reconnaissance: { open_ports: [], technologies: [], subdomains: [], directories: [] }, vulnerabilities: [], exploits: [], risk_score: 0, threat_level: 'low' }, recommendations: [] }; } private async executePhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { phase.results = []; switch (phase.name) { case 'reconnaissance': await this.executeReconPhase(workflow, phase); break; case 'web_discovery': await this.executeWebDiscoveryPhase(workflow, phase); break; case 'web_vulnerability_scan': await this.executeWebVulnPhase(workflow, phase); break; case 'network_vulnerability_scan': await this.executeNetworkVulnPhase(workflow, phase); break; case 'exploitation': await this.executeExploitationPhase(workflow, phase); break; case 'post_exploitation': await this.executePostExploitationPhase(workflow, phase); break; } } private async executeReconPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { const target = workflow.target; // Port scan const nmapResult = await this.reconTools.nmapScan(target, workflow.intensity === 'aggressive' ? 'full' : 'quick'); phase.results!.push(nmapResult); if (nmapResult.status === 'success' && nmapResult.results.open_ports) { workflow.results.reconnaissance.open_ports = nmapResult.results.open_ports; } // Subdomain enumeration (only for domain targets) if (this.isDomain(target)) { const subdomainResult = await this.reconTools.subdomainEnum(target); phase.results!.push(subdomainResult); if (subdomainResult.status === 'success' && subdomainResult.results.subdomains) { workflow.results.reconnaissance.subdomains = subdomainResult.results.subdomains; } } // Technology detection (for web targets) if (this.hasWebPort(workflow.results.reconnaissance.open_ports) || this.isURL(target)) { const webTarget = this.isURL(target) ? target : `http://${target}`; const techResult = await this.reconTools.techDetection(webTarget); phase.results!.push(techResult); if (techResult.status === 'success' && techResult.results.technologies) { workflow.results.reconnaissance.technologies = techResult.results.technologies; } } } private async executeWebDiscoveryPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { const target = workflow.target; const webTarget = this.isURL(target) ? target : `http://${target}`; // Directory brute force const dirResult = await this.reconTools.directoryBruteforce(webTarget); phase.results!.push(dirResult); if (dirResult.status === 'success' && dirResult.results.found_paths) { workflow.results.reconnaissance.directories = dirResult.results.found_paths; } } private async executeWebVulnPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { const target = workflow.target; const webTarget = this.isURL(target) ? target : `http://${target}`; // Nuclei scan for web vulnerabilities const nucleiResult = await this.vulnScanTools.nucleiScan(webTarget, ['http'], 'medium'); phase.results!.push(nucleiResult); // Nikto scan const niktoResult = await this.vulnScanTools.niktoScan(webTarget); phase.results!.push(niktoResult); // Custom web vulnerability scan const customVulnResult = await this.vulnScanTools.customWebVulnScan(webTarget); phase.results!.push(customVulnResult); // Aggregate vulnerabilities const allVulns: VulnerabilityResult[] = []; [nucleiResult, niktoResult, customVulnResult].forEach(result => { if (result.status === 'success' && result.results.vulnerabilities) { allVulns.push(...result.results.vulnerabilities); } }); workflow.results.vulnerabilities.push(...allVulns); } private async executeNetworkVulnPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { const target = workflow.target; // Network-focused Nuclei scan const nucleiResult = await this.vulnScanTools.nucleiScan(target, ['network'], 'medium'); phase.results!.push(nucleiResult); if (nucleiResult.status === 'success' && nucleiResult.results.vulnerabilities) { workflow.results.vulnerabilities.push(...nucleiResult.results.vulnerabilities); } } private async executeExploitationPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { const target = workflow.target; // Only attempt exploitation if vulnerabilities were found if (workflow.results.vulnerabilities.length === 0) { phase.status = 'skipped'; return; } // Sort vulnerabilities by severity and attempt exploitation const highSeverityVulns = workflow.results.vulnerabilities .filter(v => v.severity === 'high' || v.severity === 'critical') .slice(0, 3); // Limit to top 3 for safety for (const vuln of highSeverityVulns) { const exploitResult = await this.exploitTools.exploitAttempt(target, vuln.name); phase.results!.push(exploitResult); if (exploitResult.status === 'success' && exploitResult.results.successful_exploits) { workflow.results.exploits.push(...exploitResult.results.successful_exploits); } } } private async executePostExploitationPhase(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { // Only execute if we have successful exploits if (workflow.results.exploits.length === 0) { phase.status = 'skipped'; return; } // Post-exploitation activities would go here // For now, just document the successful exploits console.error(`Post-exploitation phase: ${workflow.results.exploits.length} successful exploits to analyze`); } private async analyzePhaseResults(workflow: PentestWorkflow, phase: WorkflowPhase): Promise<void> { // Analyze results and potentially modify subsequent phases if (phase.name === 'reconnaissance') { // If no web ports found, skip web phases if (!this.hasWebPort(workflow.results.reconnaissance.open_ports) && !this.isURL(workflow.target)) { workflow.phases.forEach(p => { if (p.name.includes('web')) { p.status = 'skipped'; } }); } } if (phase.name === 'web_vulnerability_scan' || phase.name === 'network_vulnerability_scan') { // If no high-severity vulnerabilities found, consider skipping exploitation const highSeverityVulns = workflow.results.vulnerabilities.filter(v => v.severity === 'high' || v.severity === 'critical' ); if (highSeverityVulns.length === 0 && workflow.intensity !== 'aggressive') { const exploitPhase = workflow.phases.find(p => p.name === 'exploitation'); if (exploitPhase) { exploitPhase.status = 'skipped'; } } } } private shouldAbortOnFailure(phase: WorkflowPhase, error: any): boolean { // Critical failures that should abort the workflow if (phase.name === 'reconnaissance') { // If recon fails completely, we can't continue return true; } // For other phases, continue with remaining phases return false; } private calculateFinalRiskScore(workflow: PentestWorkflow): void { let score = 0; // Score based on open ports (max 20 points) score += Math.min(workflow.results.reconnaissance.open_ports.length * 2, 20); // Score based on vulnerabilities (max 50 points) workflow.results.vulnerabilities.forEach(vuln => { switch (vuln.severity) { case 'critical': score += 10; break; case 'high': score += 7; break; case 'medium': score += 4; break; case 'low': score += 2; break; case 'info': score += 1; break; } }); score = Math.min(score, 70); // Cap vulnerability score // Score based on successful exploits (max 30 points) score += Math.min(workflow.results.exploits.length * 10, 30); workflow.results.risk_score = Math.min(score, 100); // Determine threat level if (score >= 80) { workflow.results.threat_level = 'critical'; } else if (score >= 60) { workflow.results.threat_level = 'high'; } else if (score >= 30) { workflow.results.threat_level = 'medium'; } else { workflow.results.threat_level = 'low'; } } private generateFinalRecommendations(workflow: PentestWorkflow): void { const recommendations: string[] = []; // Port-based recommendations if (workflow.results.reconnaissance.open_ports.length > 10) { recommendations.push('Reduce attack surface by closing unnecessary ports'); } // Vulnerability-based recommendations const criticalVulns = workflow.results.vulnerabilities.filter(v => v.severity === 'critical'); if (criticalVulns.length > 0) { recommendations.push(`Address ${criticalVulns.length} critical vulnerabilities immediately`); } // Exploit-based recommendations if (workflow.results.exploits.length > 0) { recommendations.push('Implement additional security controls - active exploitation successful'); } // Technology-based recommendations const outdatedTech = workflow.results.reconnaissance.technologies.filter(t => t.technology.toLowerCase().includes('apache') && t.version ); if (outdatedTech.length > 0) { recommendations.push('Update server software and frameworks to latest versions'); } workflow.recommendations = recommendations; } private analyzeReconResults(recon: any): NextStepsRecommendation[] { const recommendations: NextStepsRecommendation[] = []; if (recon.open_ports && recon.open_ports.length > 0) { const webPorts = recon.open_ports.filter((p: any) => p.port === 80 || p.port === 443 || p.port === 8080); if (webPorts.length > 0) { recommendations.push({ priority: 'high', action: 'Perform web application vulnerability scan', tool: 'nuclei_scan', reason: 'Web services detected on target', estimated_time: '10-30 minutes', risk_level: 'medium' }); } const sshPorts = recon.open_ports.filter((p: any) => p.port === 22); if (sshPorts.length > 0) { recommendations.push({ priority: 'medium', action: 'Test SSH for weak credentials', tool: 'ssh_bruteforce', reason: 'SSH service exposed', estimated_time: '30-60 minutes', risk_level: 'high' }); } } return recommendations; } private analyzeVulnResults(vulnerabilities: VulnerabilityResult[]): NextStepsRecommendation[] { const recommendations: NextStepsRecommendation[] = []; const criticalVulns = vulnerabilities.filter(v => v.severity === 'critical'); const highVulns = vulnerabilities.filter(v => v.severity === 'high'); if (criticalVulns.length > 0) { recommendations.push({ priority: 'high', action: 'Attempt exploitation of critical vulnerabilities', tool: 'exploit_attempt', reason: `${criticalVulns.length} critical vulnerabilities found`, estimated_time: '15-45 minutes', risk_level: 'critical' }); } if (highVulns.length > 0) { recommendations.push({ priority: 'medium', action: 'Investigate high severity vulnerabilities', tool: 'manual_verification', reason: `${highVulns.length} high severity vulnerabilities found`, estimated_time: '20-60 minutes', risk_level: 'high' }); } return recommendations; } private analyzeExploitResults(exploits: ExploitResult[]): NextStepsRecommendation[] { const recommendations: NextStepsRecommendation[] = []; const successfulExploits = exploits.filter(e => e.success); if (successfulExploits.length > 0) { recommendations.push({ priority: 'high', action: 'Perform post-exploitation activities', tool: 'post_exploitation', reason: `${successfulExploits.length} successful exploits achieved`, estimated_time: '30-120 minutes', risk_level: 'critical' }); } return recommendations; } private generateAnalysisSummary(results: any): any { return { total_open_ports: results.reconnaissance?.open_ports?.length || 0, total_vulnerabilities: results.vulnerabilities?.length || 0, successful_exploits: results.exploits?.filter((e: any) => e.success)?.length || 0, risk_assessment: results.risk_score >= 70 ? 'High Risk' : results.risk_score >= 40 ? 'Medium Risk' : 'Low Risk' }; } // Utility methods private isDomain(target: string): boolean { return /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.test(target); } private isURL(target: string): boolean { return target.startsWith('http://') || target.startsWith('https://'); } private hasWebPort(ports: PortScanResult[]): boolean { return ports.some(p => p.port === 80 || p.port === 443 || p.port === 8080 || p.port === 8443); } }

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/adriyansyah-mf/mcp-pentest'

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