Skip to main content
Glama

MCP Pentest

cve-discovery.ts•16.3 kB
import axios from 'axios'; import { ScanResult, TechDetectionResult } from './recon.js'; export interface CVEResult { cve_id: string; cvss_score: number; severity: 'low' | 'medium' | 'high' | 'critical'; description: string; published_date: string; modified_date: string; affected_product: string; affected_version: string; references: string[]; exploit_available: boolean; exploit_links: string[]; cwe_id?: string; vector_string?: string; } export interface CVEDatabase { nvd: CVEResult[]; exploit_db: CVEResult[]; vulners: CVEResult[]; mitre: CVEResult[]; } export class CVEDiscoveryEngine { async discoverCVEs(technologies: TechDetectionResult[]): Promise<ScanResult> { try { const cveResults: CVEResult[] = []; console.error(`šŸ” Discovering CVEs for ${technologies.length} technologies...`); for (const tech of technologies) { console.error(` Searching CVEs for ${tech.technology} ${tech.version || ''}`); // Search multiple CVE databases const nvdResults = await this.searchNVD(tech); const exploitDbResults = await this.searchExploitDB(tech); const vulnersResults = await this.searchVulners(tech); const mitreResults = await this.searchMITRE(tech); cveResults.push(...nvdResults, ...exploitDbResults, ...vulnersResults, ...mitreResults); } // Remove duplicates and sort by CVSS score const uniqueCVEs = this.deduplicateCVEs(cveResults); const sortedCVEs = uniqueCVEs.sort((a, b) => b.cvss_score - a.cvss_score); return { target: 'cve_discovery', timestamp: new Date().toISOString(), tool: 'cve_discovery', results: { total_cves_found: sortedCVEs.length, critical_cves: sortedCVEs.filter(c => c.severity === 'critical').length, high_cves: sortedCVEs.filter(c => c.severity === 'high').length, exploitable_cves: sortedCVEs.filter(c => c.exploit_available).length, cves: sortedCVEs.slice(0, 50), // Top 50 most critical technology_coverage: technologies.map(t => ({ technology: t.technology, version: t.version, cve_count: sortedCVEs.filter(c => c.affected_product.toLowerCase().includes(t.technology.toLowerCase()) ).length })) }, status: 'success' }; } catch (error) { return { target: 'cve_discovery', timestamp: new Date().toISOString(), tool: 'cve_discovery', results: {}, status: 'error', error: error instanceof Error ? error.message : String(error) }; } } async searchCVEByService(service: string, version?: string, port?: number): Promise<CVEResult[]> { try { const searchQueries = [ `${service} ${version || ''}`.trim(), `${service} vulnerability`, port ? `port ${port} vulnerability` : '' ].filter(q => q); const allResults: CVEResult[] = []; for (const query of searchQueries) { const nvdResults = await this.searchNVDByKeyword(query); const exploitResults = await this.searchExploitDBByKeyword(query); allResults.push(...nvdResults, ...exploitResults); } return this.deduplicateCVEs(allResults); } catch (error) { console.error('CVE search error:', error); return []; } } private async searchNVD(tech: TechDetectionResult): Promise<CVEResult[]> { try { // NVD API v2.0 const baseUrl = 'https://services.nvd.nist.gov/rest/json/cves/2.0'; const keyword = `${tech.technology} ${tech.version || ''}`.trim(); const response = await axios.get(baseUrl, { params: { keywordSearch: keyword, resultsPerPage: 20, keywordExactMatch: false }, timeout: 15000, headers: { 'User-Agent': 'MCP-Pentest-Framework/1.0' } }); const cves: CVEResult[] = []; if (response.data.vulnerabilities) { for (const vuln of response.data.vulnerabilities) { const cve = vuln.cve; // Extract CVSS score let cvssScore = 0; let severity: 'low' | 'medium' | 'high' | 'critical' = 'low'; if (cve.metrics?.cvssMetricV31?.[0]) { cvssScore = cve.metrics.cvssMetricV31[0].cvssData.baseScore; severity = this.calculateSeverity(cvssScore); } else if (cve.metrics?.cvssMetricV30?.[0]) { cvssScore = cve.metrics.cvssMetricV30[0].cvssData.baseScore; severity = this.calculateSeverity(cvssScore); } else if (cve.metrics?.cvssMetricV2?.[0]) { cvssScore = cve.metrics.cvssMetricV2[0].cvssData.baseScore; severity = this.calculateSeverity(cvssScore); } // Check for exploits const exploitAvailable = await this.checkExploitAvailability(cve.id); cves.push({ cve_id: cve.id, cvss_score: cvssScore, severity, description: cve.descriptions?.[0]?.value || 'No description available', published_date: cve.published, modified_date: cve.lastModified, affected_product: tech.technology, affected_version: tech.version || 'Unknown', references: cve.references?.map((ref: any) => ref.url) || [], exploit_available: exploitAvailable.available, exploit_links: exploitAvailable.links, cwe_id: cve.weaknesses?.[0]?.description?.[0]?.value, vector_string: cve.metrics?.cvssMetricV31?.[0]?.cvssData?.vectorString }); } } return cves; } catch (error) { console.error('NVD search error:', error); return []; } } private async searchExploitDB(tech: TechDetectionResult): Promise<CVEResult[]> { try { // Exploit-DB API (unofficial/scraping) const searchTerm = `${tech.technology} ${tech.version || ''}`.trim(); // Using Google search for Exploit-DB (safer than scraping) const searchUrl = `https://www.googleapis.com/customsearch/v1`; // Note: This would need a Google Custom Search API key // For demo purposes, we'll simulate results const mockResults: CVEResult[] = []; // Simulate exploit search based on common vulnerable technologies if (tech.technology.toLowerCase().includes('apache')) { mockResults.push({ cve_id: 'CVE-2021-44228', // Log4j example cvss_score: 10.0, severity: 'critical', description: 'Apache Log4j2 Remote Code Execution', published_date: '2021-12-10', modified_date: '2021-12-10', affected_product: tech.technology, affected_version: tech.version || 'Multiple', references: ['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228'], exploit_available: true, exploit_links: ['https://www.exploit-db.com/exploits/50592'], cwe_id: 'CWE-502' }); } if (tech.technology.toLowerCase().includes('wordpress')) { mockResults.push({ cve_id: 'CVE-2023-6000', cvss_score: 8.8, severity: 'high', description: 'WordPress Core Authentication Bypass', published_date: '2023-10-01', modified_date: '2023-10-01', affected_product: tech.technology, affected_version: tech.version || 'Unknown', references: ['https://wordpress.org/news/'], exploit_available: true, exploit_links: ['https://www.exploit-db.com/exploits/51234'], cwe_id: 'CWE-287' }); } return mockResults; } catch (error) { console.error('Exploit-DB search error:', error); return []; } } private async searchVulners(tech: TechDetectionResult): Promise<CVEResult[]> { try { // Vulners.com API const apiKey = process.env.VULNERS_API_KEY; if (!apiKey) { console.warn('Vulners API key not configured'); return []; } const searchQuery = `${tech.technology} ${tech.version || ''}`.trim(); const response = await axios.post('https://vulners.com/api/v3/search/lucene/', { query: searchQuery, skip: 0, size: 20 }, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 }); const cves: CVEResult[] = []; if (response.data.result === 'OK' && response.data.data.search) { for (const item of response.data.data.search) { if (item._source.type === 'cve') { cves.push({ cve_id: item._source.id, cvss_score: item._source.cvss?.score || 0, severity: this.calculateSeverity(item._source.cvss?.score || 0), description: item._source.description || 'No description', published_date: item._source.published || '', modified_date: item._source.modified || '', affected_product: tech.technology, affected_version: tech.version || 'Unknown', references: item._source.references || [], exploit_available: item._source.exploits?.length > 0, exploit_links: item._source.exploits || [], cwe_id: item._source.cwe?.[0] }); } } } return cves; } catch (error) { console.error('Vulners search error:', error); return []; } } private async searchMITRE(tech: TechDetectionResult): Promise<CVEResult[]> { try { // MITRE CVE database search (simplified) const searchTerm = tech.technology.toLowerCase(); const mockResults: CVEResult[] = []; // Common CVEs based on technology patterns const techPatterns = { 'php': [ { cve_id: 'CVE-2023-0662', cvss_score: 7.5, description: 'PHP Remote File Inclusion vulnerability' } ], 'mysql': [ { cve_id: 'CVE-2023-21912', cvss_score: 6.5, description: 'MySQL Server privilege escalation' } ], 'nginx': [ { cve_id: 'CVE-2023-44487', cvss_score: 7.5, description: 'Nginx HTTP/2 Rapid Reset Attack' } ] }; for (const [pattern, cves] of Object.entries(techPatterns)) { if (searchTerm.includes(pattern)) { for (const cve of cves) { mockResults.push({ ...cve, severity: this.calculateSeverity(cve.cvss_score), published_date: '2023-01-01', modified_date: '2023-01-01', affected_product: tech.technology, affected_version: tech.version || 'Multiple', references: [`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${cve.cve_id}`], exploit_available: false, exploit_links: [] }); } } } return mockResults; } catch (error) { console.error('MITRE search error:', error); return []; } } private async searchNVDByKeyword(keyword: string): Promise<CVEResult[]> { try { const baseUrl = 'https://services.nvd.nist.gov/rest/json/cves/2.0'; const response = await axios.get(baseUrl, { params: { keywordSearch: keyword, resultsPerPage: 10 }, timeout: 10000 }); const cves: CVEResult[] = []; if (response.data.vulnerabilities) { for (const vuln of response.data.vulnerabilities) { const cve = vuln.cve; let cvssScore = 0; if (cve.metrics?.cvssMetricV31?.[0]) { cvssScore = cve.metrics.cvssMetricV31[0].cvssData.baseScore; } const exploitCheck = await this.checkExploitAvailability(cve.id); cves.push({ cve_id: cve.id, cvss_score: cvssScore, severity: this.calculateSeverity(cvssScore), description: cve.descriptions?.[0]?.value || 'No description', published_date: cve.published, modified_date: cve.lastModified, affected_product: keyword, affected_version: 'Unknown', references: cve.references?.map((ref: any) => ref.url) || [], exploit_available: exploitCheck.available, exploit_links: exploitCheck.links }); } } return cves; } catch (error) { console.error('NVD keyword search error:', error); return []; } } private async searchExploitDBByKeyword(keyword: string): Promise<CVEResult[]> { // This would integrate with Exploit-DB API or searchsploit // For now, return empty array return []; } private async checkExploitAvailability(cveId: string): Promise<{ available: boolean; links: string[] }> { try { // Check multiple exploit databases const exploitSources = [ `https://www.exploit-db.com/search?cve=${cveId}`, `https://github.com/search?q=${cveId}+exploit&type=repositories`, `https://www.rapid7.com/db/?q=${cveId}`, `https://packetstormsecurity.com/search/?q=${cveId}` ]; // Simulate exploit availability check // In real implementation, this would make HTTP requests to check const hasExploit = Math.random() > 0.7; // 30% chance of having exploit return { available: hasExploit, links: hasExploit ? exploitSources.slice(0, 2) : [] }; } catch (error) { return { available: false, links: [] }; } } private calculateSeverity(cvssScore: number): 'low' | 'medium' | 'high' | 'critical' { if (cvssScore >= 9.0) return 'critical'; if (cvssScore >= 7.0) return 'high'; if (cvssScore >= 4.0) return 'medium'; return 'low'; } private deduplicateCVEs(cves: CVEResult[]): CVEResult[] { const seen = new Set<string>(); return cves.filter(cve => { if (seen.has(cve.cve_id)) { return false; } seen.add(cve.cve_id); return true; }); } async generateCVEReport(cves: CVEResult[], target: string): Promise<string> { const criticalCVEs = cves.filter(c => c.severity === 'critical'); const highCVEs = cves.filter(c => c.severity === 'high'); const exploitableCVEs = cves.filter(c => c.exploit_available); let report = `# CVE Discovery Report - ${target}\n\n`; report += `**Generated:** ${new Date().toLocaleString()}\n`; report += `**Total CVEs Found:** ${cves.length}\n`; report += `**Critical:** ${criticalCVEs.length}\n`; report += `**High:** ${highCVEs.length}\n`; report += `**With Exploits:** ${exploitableCVEs.length}\n\n`; if (criticalCVEs.length > 0) { report += `## 🚨 Critical CVEs\n\n`; for (const cve of criticalCVEs.slice(0, 10)) { report += `### ${cve.cve_id} (CVSS: ${cve.cvss_score})\n`; report += `**Product:** ${cve.affected_product} ${cve.affected_version}\n`; report += `**Description:** ${cve.description}\n`; if (cve.exploit_available) { report += `**āš ļø EXPLOIT AVAILABLE**\n`; report += `**Exploit Links:** ${cve.exploit_links.join(', ')}\n`; } report += `**References:** ${cve.references.slice(0, 3).join(', ')}\n\n`; } } if (exploitableCVEs.length > 0) { report += `## šŸ’„ CVEs with Public Exploits\n\n`; for (const cve of exploitableCVEs.slice(0, 15)) { report += `- **${cve.cve_id}** (${cve.severity.toUpperCase()}) - ${cve.affected_product}\n`; report += ` - CVSS: ${cve.cvss_score}\n`; report += ` - Exploits: ${cve.exploit_links.join(', ')}\n\n`; } } return report; } }

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