@iota-big3/sdk-security
Version:
Advanced security features including zero trust, quantum-safe crypto, and ML threat detection
820 lines (792 loc) • 33.3 kB
JavaScript
;
/**
* Penetration Testing Manager
* Central orchestrator for security testing operations
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PenTestManager = void 0;
const tslib_1 = require("tslib");
const crypto = tslib_1.__importStar(require("crypto"));
const events_1 = require("events");
const exploit_engine_1 = require("./exploit-engine");
const network_scanner_1 = require("./scanners/network-scanner");
const web_scanner_1 = require("./scanners/web-scanner");
const types_1 = require("./types");
class PenTestManager extends events_1.EventEmitter {
constructor(config = {}) {
super();
this.sessions = new Map();
this.activeSessions = new Set();
this.config = {
maxConcurrentTests: config.maxConcurrentTests || 5,
autoExploit: config.autoExploit ?? false,
safeMode: config.safeMode ?? true,
reportPath: config.reportPath || './pentest-reports'
};
// Initialize scanners and exploit engine
this.networkScanner = new network_scanner_1.NetworkScanner();
this.webScanner = new web_scanner_1.WebScanner();
this.exploitEngine = new exploit_engine_1.ExploitEngine();
this.setupEventHandlers();
}
/**
* Create a new penetration test session
*/
async createSession(config) {
// Validate authorization
if (!config.authorization.authorized) {
throw new Error('Penetration test must be authorized');
}
const sessionId = crypto.randomUUID();
const session = {
id: sessionId,
projectName: `PenTest-${new Date().toISOString().split('T')[0]}`,
startTime: new Date(),
status: types_1.TestStatus.PLANNING,
config,
testers: [],
vulnerabilities: [],
statistics: this.initializeStatistics(),
timeline: [],
reports: []
};
// Add initial timeline event
this.addTimelineEvent(session, {
type: types_1.EventType.TEST_STARTED,
description: 'Penetration test session created',
tester: 'System'
});
this.sessions.set(sessionId, session);
this.emit('session:created', { sessionId, config });
return session;
}
/**
* Get session by ID
*/
async getSession(id) {
const session = this.sessions.get(id);
if (!session) {
throw new Error(`Session ${id} not found`);
}
return session;
}
/**
* Update session
*/
async updateSession(id, updates) {
const session = await this.getSession(id);
Object.assign(session, updates);
this.emit('session:updated', { sessionId: id, updates });
}
/**
* Start penetration test
*/
async startTest(sessionId) {
const session = await this.getSession(sessionId);
if (session.status !== types_1.TestStatus.PLANNING) {
throw new Error(`Cannot start test in ${session.status} status`);
}
// Check concurrent test limit
if (this.activeSessions.size >= this.config.maxConcurrentTests) {
throw new Error('Maximum concurrent tests reached');
}
session.status = types_1.TestStatus.IN_PROGRESS;
this.activeSessions.add(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.TEST_STARTED,
description: 'Penetration test started',
tester: 'System'
});
this.emit('test:started', { sessionId });
// Start automated testing based on config
this.runAutomatedTests(session);
}
/**
* Pause test
*/
async pauseTest(sessionId) {
const session = await this.getSession(sessionId);
if (session.status !== types_1.TestStatus.IN_PROGRESS) {
throw new Error('Can only pause in-progress tests');
}
session.status = types_1.TestStatus.PAUSED;
this.activeSessions.delete(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.OTHER,
description: 'Test paused',
tester: 'System'
});
this.emit('test:paused', { sessionId });
}
/**
* Resume test
*/
async resumeTest(sessionId) {
const session = await this.getSession(sessionId);
if (session.status !== types_1.TestStatus.PAUSED) {
throw new Error('Can only resume paused tests');
}
session.status = types_1.TestStatus.IN_PROGRESS;
this.activeSessions.add(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.OTHER,
description: 'Test resumed',
tester: 'System'
});
this.emit('test:resumed', { sessionId });
}
/**
* Stop test
*/
async stopTest(sessionId) {
const session = await this.getSession(sessionId);
session.status = types_1.TestStatus.COMPLETED;
session.endTime = new Date();
this.activeSessions.delete(sessionId);
// Calculate final statistics
this.updateStatistics(session);
this.addTimelineEvent(session, {
type: types_1.EventType.TEST_COMPLETED,
description: 'Penetration test completed',
tester: 'System'
});
this.emit('test:completed', { sessionId });
// Auto-generate report if configured
if (session.config.reporting.executiveSummary) {
await this.generateReport(sessionId, session.config.reporting);
}
}
/**
* Scan specific target
*/
async scanTarget(sessionId, target) {
const session = await this.getSession(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_STARTED,
description: `Scanning target: ${target.address}`,
tester: 'NetworkScanner',
target: target.address
});
const result = await this.networkScanner.scanTarget(target);
// Add vulnerabilities to session
session.vulnerabilities.push(...result.vulnerabilities);
session.statistics.targetsScanned++;
session.statistics.vulnerabilitiesFound += result.vulnerabilities.length;
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_COMPLETED,
description: `Scan completed: ${result.vulnerabilities.length} vulnerabilities found`,
tester: 'NetworkScanner',
target: target.address
});
// Auto-exploit if configured
if (this.config.autoExploit) {
for (const vuln of result.vulnerabilities) {
if (this.exploitEngine.isSafeToExploit(vuln)) {
await this.exploitVulnerability(vuln.id);
}
}
}
return result;
}
/**
* Scan network range
*/
async scanNetwork(sessionId, range) {
const session = await this.getSession(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_STARTED,
description: `Network scan started: ${range}`,
tester: 'NetworkScanner'
});
const result = await this.networkScanner.scanNetwork(range);
// Update session
session.vulnerabilities.push(...result.vulnerabilities);
session.statistics.targetsScanned += result.discoveredHosts.length;
session.statistics.vulnerabilitiesFound += result.vulnerabilities.length;
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_COMPLETED,
description: `Network scan completed: ${result.discoveredHosts.length} hosts, ${result.vulnerabilities.length} vulnerabilities`,
tester: 'NetworkScanner'
});
return result;
}
/**
* Scan web application
*/
async scanWebApp(sessionId, url) {
const session = await this.getSession(sessionId);
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_STARTED,
description: `Web application scan started: ${url}`,
tester: 'WebScanner'
});
const result = await this.webScanner.scanWebApp(url);
// Update session
session.vulnerabilities.push(...result.vulnerabilities);
session.statistics.vulnerabilitiesFound += result.vulnerabilities.length;
// Update vulnerability categories
result.vulnerabilities.forEach(vuln => {
session.statistics.vulnerabilitiesByCategory[vuln.category] =
(session.statistics.vulnerabilitiesByCategory[vuln.category] || 0) + 1;
});
this.addTimelineEvent(session, {
type: types_1.EventType.SCAN_COMPLETED,
description: `Web scan completed: ${result.vulnerabilities.length} vulnerabilities found`,
tester: 'WebScanner'
});
return result;
}
/**
* Report vulnerability
*/
async reportVulnerability(sessionId, vuln) {
const session = await this.getSession(sessionId);
// Check if already reported
if (!session.vulnerabilities.find(v => v.id === vuln.id)) {
session.vulnerabilities.push(vuln);
session.statistics.vulnerabilitiesFound++;
// Update severity counts
if (vuln.severity === 'CRITICAL')
session.statistics.criticalVulnerabilities++;
if (vuln.severity === 'HIGH')
session.statistics.highVulnerabilities++;
this.addTimelineEvent(session, {
type: types_1.EventType.VULNERABILITY_FOUND,
description: vuln.title,
tester: vuln.discoveredBy,
severity: vuln.severity
});
this.emit('vulnerability:found', { sessionId, vulnerability: vuln });
}
}
/**
* Verify vulnerability
*/
async verifyVulnerability(vulnId) {
// Find vulnerability across all sessions
let vulnerability;
let session;
for (const [id, s] of this.sessions) {
const v = s.vulnerabilities.find(vuln => vuln.id === vulnId);
if (v) {
vulnerability = v;
session = s;
break;
}
}
if (!vulnerability || !session) {
throw new Error(`Vulnerability ${vulnId} not found`);
}
// Mock verification - in production would re-test
const verified = Math.random() > 0.2; // 80% verification rate
this.addTimelineEvent(session, {
type: types_1.EventType.FINDING_VERIFIED,
description: `Vulnerability ${verified ? 'verified' : 'not reproducible'}: ${vulnerability.title}`,
tester: 'System'
});
return verified;
}
/**
* Exploit vulnerability
*/
async exploitVulnerability(vulnId) {
// Find vulnerability
let vulnerability;
let session;
for (const [id, s] of this.sessions) {
const v = s.vulnerabilities.find(vuln => vuln.id === vulnId);
if (v) {
vulnerability = v;
session = s;
break;
}
}
if (!vulnerability || !session) {
throw new Error(`Vulnerability ${vulnId} not found`);
}
// Check safe mode
if (this.config.safeMode && !this.exploitEngine.isSafeToExploit(vulnerability)) {
throw new Error('Exploitation blocked by safe mode');
}
this.addTimelineEvent(session, {
type: types_1.EventType.EXPLOIT_ATTEMPTED,
description: `Attempting to exploit: ${vulnerability.title}`,
tester: 'ExploitEngine'
});
const result = await this.exploitEngine.exploitVulnerability(vulnerability);
if (result.success) {
session.statistics.exploitsSuccessful++;
this.addTimelineEvent(session, {
type: types_1.EventType.EXPLOIT_SUCCESSFUL,
description: `Successfully exploited: ${vulnerability.title}`,
tester: 'ExploitEngine'
});
}
else {
this.addTimelineEvent(session, {
type: types_1.EventType.EXPLOIT_FAILED,
description: `Failed to exploit: ${vulnerability.title}`,
tester: 'ExploitEngine'
});
}
return result;
}
/**
* Generate report
*/
async generateReport(sessionId, config) {
const session = await this.getSession(sessionId);
const report = {
id: crypto.randomUUID(),
title: `Penetration Test Report - ${session.projectName}`,
type: config.detail,
generatedAt: new Date(),
generatedBy: 'PenTestManager',
format: config.format[0] || types_1.ReportFormat.PDF,
findings: this.prepareFindings(session, config),
recommendations: this.generateRecommendations(session),
conclusion: this.generateConclusion(session)
};
// Add sections based on config
if (config.executiveSummary) {
report.executiveSummary = this.generateExecutiveSummary(session);
}
report.methodology = this.generateMethodology(session);
report.scope = this.generateScope(session);
if (config.technicalAppendix) {
report.appendices = this.generateAppendices(session);
}
session.reports.push(report);
this.emit('report:generated', { sessionId, reportId: report.id });
return report;
}
/**
* Export report
*/
async exportReport(reportId, format) {
// Find report
let report;
for (const [, session] of this.sessions) {
const r = session.reports.find(rep => rep.id === reportId);
if (r) {
report = r;
break;
}
}
if (!report) {
throw new Error(`Report ${reportId} not found`);
}
switch (format) {
case types_1.ReportFormat.JSON:
return Buffer.from(JSON.stringify(report, null, 2));
case types_1.ReportFormat.HTML:
return this.exportToHTML(report);
case types_1.ReportFormat.MARKDOWN:
return this.exportToMarkdown(report);
case types_1.ReportFormat.PDF:
case types_1.ReportFormat.XML:
default:
// In production, would use proper libraries
return this.exportToHTML(report);
}
}
/**
* Private helper methods
*/
setupEventHandlers() {
// Forward scanner events
this.networkScanner.on('scan:completed', (data) => {
this.emit('scan:completed', data);
});
this.webScanner.on('vulnerability:found', (data) => {
this.emit('vulnerability:found', data);
});
this.exploitEngine.on('exploit:successful', (data) => {
this.emit('exploit:successful', data);
});
}
initializeStatistics() {
return {
totalTargets: 0,
targetsScanned: 0,
vulnerabilitiesFound: 0,
criticalVulnerabilities: 0,
highVulnerabilities: 0,
exploitsSuccessful: 0,
testDuration: 0,
vulnerabilitiesByCategory: {},
coveragePercentage: 0,
testTypesCompleted: []
};
}
addTimelineEvent(session, event) {
session.timeline.push({
...event,
timestamp: new Date()
});
}
async runAutomatedTests(session) {
// Run tests based on configuration
for (const testType of session.config.testTypes) {
if (session.status !== types_1.TestStatus.IN_PROGRESS)
break;
try {
switch (testType) {
case 'NETWORK':
await this.runNetworkTests(session);
break;
case 'WEB_APPLICATION':
await this.runWebTests(session);
break;
case 'API':
await this.runAPITests(session);
break;
default:
this.emit('test:skipped', {
sessionId: session.id,
testType,
reason: 'Not implemented'
});
}
session.statistics.testTypesCompleted.push(testType);
}
catch (error) {
this.emit('test:error', {
sessionId: session.id,
testType,
error
});
}
}
// Auto-complete if all tests done
if (session.status === types_1.TestStatus.IN_PROGRESS) {
await this.stopTest(session.id);
}
}
async runNetworkTests(session) {
const { targets, ipRanges } = session.config.scope;
// Scan individual targets
for (const target of targets) {
if (target.type === 'HOST' || target.type === 'NETWORK') {
await this.scanTarget(session.id, target);
}
}
// Scan IP ranges
if (ipRanges) {
for (const range of ipRanges) {
await this.scanNetwork(session.id, range);
}
}
}
async runWebTests(session) {
const { applications, domains } = session.config.scope;
// Scan applications
if (applications) {
for (const app of applications) {
await this.scanWebApp(session.id, app.url);
}
}
// Scan domains
if (domains) {
for (const domain of domains) {
await this.scanWebApp(session.id, `https://${domain}`);
}
}
}
async runAPITests(session) {
// API testing would be implemented here
this.emit('test:info', {
sessionId: session.id,
message: 'API testing not yet implemented'
});
}
updateStatistics(session) {
const duration = session.endTime
? (session.endTime.getTime() - session.startTime.getTime()) / (1000 * 60 * 60)
: 0;
session.statistics.testDuration = duration;
// Calculate coverage
const scanned = session.statistics.targetsScanned;
const total = session.statistics.totalTargets || session.config.scope.targets.length;
session.statistics.coveragePercentage = total > 0 ? (scanned / total) * 100 : 0;
// Count by severity
session.statistics.criticalVulnerabilities = session.vulnerabilities
.filter(v => v.severity === 'CRITICAL').length;
session.statistics.highVulnerabilities = session.vulnerabilities
.filter(v => v.severity === 'HIGH').length;
}
prepareFindings(session, config) {
return session.vulnerabilities
.sort((a, b) => {
const severityOrder = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3, INFO: 4 };
return severityOrder[a.severity] - severityOrder[b.severity];
})
.map(vuln => ({
vulnerability: vuln,
risk: this.calculateRisk(vuln),
exploited: vuln.exploitStatus === 'SUCCESSFUL',
businessContext: this.getBusinessContext(vuln),
remediationTimeline: this.getRemediationTimeline(vuln)
}));
}
calculateRisk(vuln) {
const score = vuln.riskScore || 5;
const level = score >= 8 ? 'CRITICAL' :
score >= 6 ? 'HIGH' :
score >= 4 ? 'MEDIUM' : 'LOW';
return {
score,
level,
justification: `Based on ${vuln.severity} severity, ${vuln.exploitComplexity} complexity, and ${vuln.impact.confidentiality} confidentiality impact`
};
}
getBusinessContext(vuln) {
const contexts = {
[types_1.VulnerabilityCategory.INJECTION]: 'Could lead to complete database compromise and data theft',
[types_1.VulnerabilityCategory.BROKEN_AUTHENTICATION]: 'Allows unauthorized access to user accounts',
[types_1.VulnerabilityCategory.SENSITIVE_DATA_EXPOSURE]: 'Exposes customer data and violates privacy regulations',
[types_1.VulnerabilityCategory.XXE]: 'Allows reading of system files and internal network access',
[types_1.VulnerabilityCategory.BROKEN_ACCESS_CONTROL]: 'Users can access unauthorized resources',
[types_1.VulnerabilityCategory.SECURITY_MISCONFIGURATION]: 'Weakens overall security posture',
[types_1.VulnerabilityCategory.XSS]: 'Enables theft of user sessions and credentials',
[types_1.VulnerabilityCategory.INSECURE_DESERIALIZATION]: 'Can lead to remote code execution',
[types_1.VulnerabilityCategory.USING_VULNERABLE_COMPONENTS]: 'Inherits vulnerabilities from third-party code',
[types_1.VulnerabilityCategory.INSUFFICIENT_LOGGING]: 'Prevents detection and response to attacks',
[types_1.VulnerabilityCategory.SSRF]: 'Allows access to internal systems',
[types_1.VulnerabilityCategory.CSRF]: 'Forces users to perform unwanted actions',
[types_1.VulnerabilityCategory.BUFFER_OVERFLOW]: 'Can crash systems or execute arbitrary code',
[types_1.VulnerabilityCategory.PRIVILEGE_ESCALATION]: 'Allows attackers to gain administrative access',
[types_1.VulnerabilityCategory.INFORMATION_DISCLOSURE]: 'Reveals sensitive system information',
[types_1.VulnerabilityCategory.DENIAL_OF_SERVICE]: 'Can make services unavailable to legitimate users',
[types_1.VulnerabilityCategory.BUSINESS_LOGIC]: 'Allows manipulation of business processes',
[types_1.VulnerabilityCategory.OTHER]: 'Security weakness requiring attention'
};
return contexts[vuln.category] || 'Security vulnerability requiring remediation';
}
getRemediationTimeline(vuln) {
switch (vuln.severity) {
case 'CRITICAL': return 'Immediate (within 24 hours)';
case 'HIGH': return 'Urgent (within 7 days)';
case 'MEDIUM': return 'Short-term (within 30 days)';
case 'LOW': return 'Scheduled (within 90 days)';
default: return 'As resources permit';
}
}
generateRecommendations(session) {
const recommendations = [
'Implement a vulnerability management program with regular scanning',
'Establish a security incident response team and procedures',
'Conduct security awareness training for all staff'
];
// Add specific recommendations based on findings
const categories = new Set(session.vulnerabilities.map(v => v.category));
if (categories.has(types_1.VulnerabilityCategory.INJECTION)) {
recommendations.push('Implement input validation and parameterized queries throughout the application');
}
if (categories.has(types_1.VulnerabilityCategory.BROKEN_AUTHENTICATION)) {
recommendations.push('Enforce strong password policies and implement multi-factor authentication');
}
if (categories.has(types_1.VulnerabilityCategory.SENSITIVE_DATA_EXPOSURE)) {
recommendations.push('Encrypt all sensitive data at rest and in transit');
}
if (session.statistics.criticalVulnerabilities > 0) {
recommendations.unshift('Address all critical vulnerabilities immediately before they are exploited');
}
return recommendations;
}
generateConclusion(session) {
const { vulnerabilitiesFound, criticalVulnerabilities, highVulnerabilities } = session.statistics;
if (criticalVulnerabilities > 0) {
return `The penetration test identified ${vulnerabilitiesFound} vulnerabilities, including ${criticalVulnerabilities} critical issues that pose an immediate risk to the organization. Immediate remediation is required to prevent potential compromise.`;
}
else if (highVulnerabilities > 0) {
return `The assessment revealed ${vulnerabilitiesFound} vulnerabilities, with ${highVulnerabilities} high-severity issues that could be exploited by attackers. A remediation plan should be implemented promptly.`;
}
else if (vulnerabilitiesFound > 0) {
return `The security testing discovered ${vulnerabilitiesFound} vulnerabilities of medium to low severity. While not immediately critical, these should be addressed as part of ongoing security improvements.`;
}
else {
return 'The penetration test did not identify any significant vulnerabilities. Continue with regular security assessments and maintain current security practices.';
}
}
generateExecutiveSummary(session) {
return `
## Executive Summary
This penetration test was conducted from ${session.startTime.toLocaleDateString()} to ${session.endTime?.toLocaleDateString() || 'ongoing'} to assess the security posture of the target environment.
### Key Findings:
- Total vulnerabilities discovered: ${session.statistics.vulnerabilitiesFound}
- Critical vulnerabilities: ${session.statistics.criticalVulnerabilities}
- High severity vulnerabilities: ${session.statistics.highVulnerabilities}
- Successful exploitations: ${session.statistics.exploitsSuccessful}
### Risk Assessment:
The overall security risk is ${this.getOverallRisk(session.statistics)}.
### Immediate Actions Required:
${session.statistics.criticalVulnerabilities > 0 ? '1. Address critical vulnerabilities within 24 hours' : '1. Continue monitoring and regular assessments'}
2. Implement recommended security controls
3. Schedule follow-up assessment after remediation
`.trim();
}
generateMethodology(session) {
return `
## Methodology
This penetration test followed the ${session.config.methodology} methodology with the following approach:
1. **Information Gathering**: Passive and active reconnaissance
2. **Vulnerability Scanning**: Automated and manual vulnerability identification
3. **Exploitation**: ${session.config.constraints?.exploitationAllowed ? 'Controlled exploitation of discovered vulnerabilities' : 'Exploitation simulation without actual compromise'}
4. **Post-Exploitation**: ${session.config.constraints?.dataExfiltrationAllowed ? 'Limited data access verification' : 'No data access attempted'}
5. **Reporting**: Comprehensive documentation of all findings
Test Types Performed: ${session.config.testTypes.join(', ')}
`.trim();
}
generateScope(session) {
const { targets, ipRanges, domains, applications } = session.config.scope;
return `
## Scope
### In-Scope Assets:
- Target Systems: ${targets.length}
- IP Ranges: ${ipRanges?.join(', ') || 'None'}
- Domains: ${domains?.join(', ') || 'None'}
- Applications: ${applications?.map(a => a.name).join(', ') || 'None'}
### Exclusions:
${session.config.scope.exclusions?.join('\n- ') || 'None'}
### Constraints:
- Exploitation: ${session.config.constraints?.exploitationAllowed ? 'Allowed' : 'Not Allowed'}
- DoS Testing: ${session.config.constraints?.dosAllowed ? 'Allowed' : 'Not Allowed'}
- Brute Force: ${session.config.constraints?.bruteForceAllowed ? 'Allowed' : 'Not Allowed'}
`.trim();
}
generateAppendices(session) {
return [
{
title: 'Testing Tools',
content: 'IOTA Security Scanner, Network Scanner, Web Application Scanner, Exploit Engine',
type: 'TOOLS'
},
{
title: 'OWASP Top 10 Coverage',
content: this.generateOWASPCoverage(session),
type: 'METHODOLOGY'
},
{
title: 'Detailed Timeline',
content: this.generateDetailedTimeline(session),
type: 'TECHNICAL'
}
];
}
generateOWASPCoverage(session) {
const owaspCategories = [
types_1.VulnerabilityCategory.INJECTION,
types_1.VulnerabilityCategory.BROKEN_AUTHENTICATION,
types_1.VulnerabilityCategory.SENSITIVE_DATA_EXPOSURE,
types_1.VulnerabilityCategory.XXE,
types_1.VulnerabilityCategory.BROKEN_ACCESS_CONTROL,
types_1.VulnerabilityCategory.SECURITY_MISCONFIGURATION,
types_1.VulnerabilityCategory.XSS,
types_1.VulnerabilityCategory.INSECURE_DESERIALIZATION,
types_1.VulnerabilityCategory.USING_VULNERABLE_COMPONENTS,
types_1.VulnerabilityCategory.INSUFFICIENT_LOGGING
];
const coverage = owaspCategories.map(cat => {
const found = session.vulnerabilities.filter(v => v.category === cat).length;
return `- ${cat}: ${found > 0 ? `✓ (${found} issues)` : '✗'}`;
});
return coverage.join('\n');
}
generateDetailedTimeline(session) {
return session.timeline
.slice(-50) // Last 50 events
.map(event => `${event.timestamp.toISOString()} - ${event.type}: ${event.description}`)
.join('\n');
}
getOverallRisk(stats) {
if (stats.criticalVulnerabilities > 0)
return 'CRITICAL';
if (stats.highVulnerabilities > 2)
return 'HIGH';
if (stats.vulnerabilitiesFound > 10)
return 'MEDIUM';
return 'LOW';
}
exportToHTML(report) {
const html = `
<!DOCTYPE html>
<html>
<head>
<title>${report.title}</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
h1, h2, h3 { color: #333; }
.critical { color: #d32f2f; }
.high { color: #f57c00; }
.medium { color: #fbc02d; }
.low { color: #388e3c; }
.info { color: #1976d2; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.finding { margin-bottom: 30px; padding: 20px; border-left: 4px solid #ccc; }
.finding.critical { border-color: #d32f2f; }
.finding.high { border-color: #f57c00; }
pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
</style>
</head>
<body>
<h1>${report.title}</h1>
<p><strong>Generated:</strong> ${report.generatedAt.toLocaleString()}</p>
${report.executiveSummary ? `<section>${report.executiveSummary}</section>` : ''}
<h2>Findings</h2>
${report.findings.map(f => `
<div class="finding ${f.vulnerability.severity.toLowerCase()}">
<h3>${f.vulnerability.title} <span class="${f.vulnerability.severity.toLowerCase()}">[${f.vulnerability.severity}]</span></h3>
<p>${f.vulnerability.description}</p>
<p><strong>Risk:</strong> ${f.risk.level} (Score: ${f.risk.score}/10)</p>
<p><strong>Category:</strong> ${f.vulnerability.category}</p>
<p><strong>Exploited:</strong> ${f.exploited ? 'Yes' : 'No'}</p>
${f.businessContext ? `<p><strong>Business Impact:</strong> ${f.businessContext}</p>` : ''}
<p><strong>Remediation Timeline:</strong> ${f.remediationTimeline}</p>
<h4>Remediation</h4>
<p>${f.vulnerability.remediation.summary}</p>
<ol>${f.vulnerability.remediation.steps.map(s => `<li>${s}</li>`).join('')}</ol>
</div>
`).join('')}
<h2>Recommendations</h2>
<ol>
${report.recommendations.map(r => `<li>${r}</li>`).join('')}
</ol>
<h2>Conclusion</h2>
<p>${report.conclusion}</p>
</body>
</html>
`.trim();
return Buffer.from(html);
}
exportToMarkdown(report) {
const markdown = `
# ${report.title}
**Generated:** ${report.generatedAt.toLocaleString()}
${report.executiveSummary || ''}
## Findings
${report.findings.map(f => `
### ${f.vulnerability.title} [${f.vulnerability.severity}]
${f.vulnerability.description}
- **Risk:** ${f.risk.level} (Score: ${f.risk.score}/10)
- **Category:** ${f.vulnerability.category}
- **Exploited:** ${f.exploited ? 'Yes' : 'No'}
${f.businessContext ? `- **Business Impact:** ${f.businessContext}` : ''}
- **Remediation Timeline:** ${f.remediationTimeline}
#### Remediation
${f.vulnerability.remediation.summary}
${f.vulnerability.remediation.steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}
---
`).join('\n')}
## Recommendations
${report.recommendations.map((r, i) => `${i + 1}. ${r}`).join('\n')}
## Conclusion
${report.conclusion}
`.trim();
return Buffer.from(markdown);
}
}
exports.PenTestManager = PenTestManager;
//# sourceMappingURL=pentest-manager.js.map