UNPKG

@iota-big3/sdk-security

Version:

Advanced security features including zero trust, quantum-safe crypto, and ML threat detection

909 lines (894 loc) 34.7 kB
"use strict"; /** * Disk Forensics Analyzer * Analyzes disk images for deleted files, artifacts, and timeline reconstruction */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DiskAnalyzer = void 0; const tslib_1 = require("tslib"); const crypto = tslib_1.__importStar(require("crypto")); const events_1 = require("events"); const path = tslib_1.__importStar(require("path")); const types_1 = require("../types"); class DiskAnalyzer extends events_1.EventEmitter { constructor() { super(); this.type = types_1.ForensicAnalysisType.DISK; this.knownGoodProcesses = new Set([ 'System', 'smss.exe', 'csrss.exe', 'wininit.exe', 'services.exe', 'lsass.exe', 'svchost.exe', 'winlogon.exe', 'explorer.exe' ]); this.suspiciousFiles = new Set([ 'mimikatz.exe', 'pwdump.exe', 'nc.exe', 'psexec.exe', 'procdump.exe', 'wce.exe', 'gsecdump.exe' ]); this.knownMalwareHashes = new Map([ ['8F26BA3F4D8E4A3B9F8E7D6C5B4A3928', 'Emotet'], ['A1B2C3D4E5F6789012345678901234567', 'TrickBot'], ['DEADBEEF00000000000000000000CAFE', 'Cobalt Strike'] ]); this.browserPaths = new Map([ ['Chrome', ['%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default']], ['Firefox', ['%APPDATA%\\Mozilla\\Firefox\\Profiles']], ['Edge', ['%LOCALAPPDATA%\\Microsoft\\Edge\\User Data\\Default']] ]); } /** * Analyze disk image */ async analyze(evidence) { if (evidence.type !== types_1.ForensicAnalysisType.DISK) { throw new Error('Evidence is not a disk image'); } this.emit('analysis:started', { evidenceId: evidence.id }); const findings = []; const artifacts = []; const iocs = []; const timeline = []; try { // Parse disk image const diskData = await this.parseDiskImage(evidence); // Analyze file system timeline const timelineFindings = await this.analyzeTimeline(diskData.timeline); findings.push(...timelineFindings.findings); timeline.push(...timelineFindings.timeline); // Analyze deleted files const deletedFindings = await this.analyzeDeletedFiles(diskData.deletedFiles); findings.push(...deletedFindings.findings); artifacts.push(...deletedFindings.artifacts); iocs.push(...deletedFindings.iocs); // Analyze carved files if (diskData.carvedFiles) { const carvedFindings = await this.analyzeCarvedFiles(diskData.carvedFiles); findings.push(...carvedFindings.findings); artifacts.push(...carvedFindings.artifacts); } // Analyze registry (Windows) if (diskData.registry) { const registryFindings = await this.analyzeRegistry(diskData.registry); findings.push(...registryFindings.findings); iocs.push(...registryFindings.iocs); } // Analyze browser artifacts if (diskData.browserArtifacts) { const browserFindings = await this.analyzeBrowserArtifacts(diskData.browserArtifacts); findings.push(...browserFindings.findings); iocs.push(...browserFindings.iocs); } // Analyze prefetch files (Windows) if (diskData.prefetch) { const prefetchFindings = await this.analyzePrefetch(diskData.prefetch); findings.push(...prefetchFindings.findings); } // Generate analysis result const result = { id: crypto.randomUUID(), timestamp: new Date(), analyst: 'DiskAnalyzer', type: 'Disk Analysis', tool: 'IOTA Disk Forensics', findings, artifacts, iocs, timeline: timeline.slice(0, 1000), // Limit timeline entries conclusion: this.generateConclusion(findings) }; this.emit('analysis:completed', { evidenceId: evidence.id, findingsCount: findings.length, artifactsCount: artifacts.length }); return result; } catch (error) { this.emit('analysis:failed', { evidenceId: evidence.id, error: error.message }); throw error; } } /** * Validate disk image */ async validate(evidence) { // Check file signature const header = await this.readHeader(evidence.storagePath); // Common disk image signatures const validSignatures = [ 'E01', // EnCase 'AFF', // Advanced Forensic Format 'SMART', // SMART format 'FTK', // FTK Imager 'RAW', // DD raw image 'VMDK' // VMware disk ]; return validSignatures.some(sig => header.includes(sig)); } /** * Extract artifacts from disk */ async extract(evidence, options) { const artifacts = []; // Extract deleted files if (options?.extractDeleted) { const deletedArtifacts = await this.extractDeletedFiles(evidence); artifacts.push(...deletedArtifacts); } // Extract registry hives if (options?.extractRegistry) { const regArtifacts = await this.extractRegistryHives(evidence); artifacts.push(...regArtifacts); } // Extract browser data if (options?.extractBrowserData) { const browserArtifacts = await this.extractBrowserData(evidence); artifacts.push(...browserArtifacts); } // Extract log files if (options?.extractLogs) { const logArtifacts = await this.extractLogFiles(evidence); artifacts.push(...logArtifacts); } return artifacts; } /** * Generate report */ async generateReport(analysis) { const report = ` # Disk Forensics Analysis Report **Analysis ID**: ${analysis.id} **Date**: ${analysis.timestamp.toISOString()} **Analyst**: ${analysis.analyst} **Tool**: ${analysis.tool} ## Executive Summary ${analysis.conclusion} ## Key Findings ${analysis.findings.map(f => ` ### ${f.title} (${f.severity}) - **Type**: ${f.type} - **Description**: ${f.description} ${f.location ? `- **Location**: ${f.location}` : ''} ${f.timestamp ? `- **Timestamp**: ${f.timestamp.toISOString()}` : ''} `).join('\n')} ## Recovered Artifacts Total artifacts: ${analysis.artifacts.length} ${analysis.artifacts.slice(0, 20).map(a => ` - **${a.name}** (${a.type}) - Size: ${this.formatBytes(a.size)} - Hash: ${a.hash} - Recovered from: ${a.extractedFrom} ${a.malicious ? '- **MALICIOUS**' : ''} `).join('\n')} ## Timeline Analysis Showing recent activity: ${(analysis.timeline || []).slice(0, 50).map(t => ` - **${t.timestamp.toISOString()}**: ${t.action} - File: ${t.target} ${t.actor ? `- User: ${t.actor}` : ''} `).join('\n')} ## Indicators of Compromise ${(analysis.iocs || []).map(ioc => ` - **${ioc.type}**: ${ioc.value} - Context: ${ioc.context || 'N/A'} - First seen: ${ioc.firstSeen?.toISOString() || 'Unknown'} `).join('\n')} ## Recommendations 1. Review all identified malicious files and determine scope of compromise 2. Check other systems for similar artifacts and IOCs 3. Preserve evidence for potential legal proceedings 4. Update security controls to prevent similar incidents 5. Conduct user awareness training on identified attack vectors `.trim(); return report; } /** * Export findings */ async exportFindings(analysis, format) { switch (format) { case 'json': return Buffer.from(JSON.stringify(analysis, null, 2)); case 'timeline': return this.exportTimeline(analysis); case 'forensic-xml': return this.exportForensicXML(analysis); default: throw new Error(`Unsupported export format: ${format}`); } } /** * Private helper methods */ async parseDiskImage(evidence) { // In production, would use tools like Sleuth Kit, Autopsy, or X-Ways // For demo, return mock analysis return { evidenceId: evidence.id, fileSystem: { type: 'NTFS', volumeName: 'System', volumeSerial: 'A1B2-C3D4', clusterSize: 4096, totalSize: 500 * 1024 * 1024 * 1024, // 500GB freeSpace: 150 * 1024 * 1024 * 1024 // 150GB }, timeline: this.generateMockTimeline(), deletedFiles: this.generateMockDeletedFiles(), carvedFiles: this.generateMockCarvedFiles(), registry: this.generateMockRegistry(), browserArtifacts: this.generateMockBrowserArtifacts(), prefetch: this.generateMockPrefetch() }; } async analyzeTimeline(timeline) { const findings = []; const timelineEntries = []; // Convert file activities to timeline entries for (const activity of timeline) { timelineEntries.push({ timestamp: activity.timestamp, source: 'FileSystem', action: `File ${activity.action}`, actor: activity.user, target: activity.path, details: activity.size ? `Size: ${this.formatBytes(activity.size)}` : undefined }); } // Look for suspicious patterns const recentDeletes = timeline.filter(a => a.action === 'DELETED' && a.timestamp > new Date(Date.now() - 24 * 60 * 60 * 1000)); if (recentDeletes.length > 100) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.LOG_TAMPERING, title: 'Mass File Deletion Detected', description: `${recentDeletes.length} files deleted in the last 24 hours`, evidence: recentDeletes.slice(0, 10).map(d => d.path) }); } // Check for suspicious file creations const suspiciousCreations = timeline.filter(a => a.action === 'CREATED' && this.isSuspiciousPath(a.path)); for (const creation of suspiciousCreations) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.MEDIUM, type: types_1.FindingType.SUSPICIOUS_PROCESS, title: 'Suspicious File Created', description: `Suspicious file created in ${path.dirname(creation.path)}`, evidence: [creation.path], timestamp: creation.timestamp }); } return { findings, timeline: timelineEntries }; } async analyzeDeletedFiles(deletedFiles) { const findings = []; const artifacts = []; const iocs = []; for (const file of deletedFiles) { // Check for suspicious deleted files const filename = path.basename(file.path); if (this.suspiciousFiles.has(filename)) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.DELETED_FILE, title: `Suspicious File Deleted: ${filename}`, description: 'Known malicious tool was deleted from system', evidence: [file.path], timestamp: file.deletedAt, metadata: { file } }); // Add as IOC if (file.hash) { iocs.push({ type: types_1.IOCType.FILE_HASH, value: file.hash, context: `Deleted file: ${file.path}`, confidence: 90 }); } } // Check for known malware by hash if (file.hash && this.knownMalwareHashes.has(file.hash)) { const malwareName = this.knownMalwareHashes.get(file.hash); findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.CRITICAL, type: types_1.FindingType.MALWARE, title: `Known Malware Deleted: ${malwareName}`, description: `File matching ${malwareName} signature was deleted`, evidence: [file.hash], location: file.path }); } // Create artifact for recoverable files if (file.recoverable && file.recovered) { artifacts.push({ id: crypto.randomUUID(), name: filename, type: this.getArtifactType(file.path), path: file.path, size: file.size, hash: file.hash || 'pending', extractedFrom: 'deleted_files', extractedAt: new Date(), malicious: this.suspiciousFiles.has(filename), metadata: { deletedAt: file.deletedAt, recoverable: file.recoverable } }); } } return { findings, artifacts, iocs }; } async analyzeCarvedFiles(carvedFiles) { const findings = []; const artifacts = []; for (const file of carvedFiles) { if (file.recovered) { // Check file headers for suspicious types if (file.type === 'executable' || file.type === 'script') { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.MEDIUM, type: types_1.FindingType.SUSPICIOUS_PROCESS, title: `Carved ${file.type} File`, description: `Recovered ${file.type} file from unallocated space`, evidence: [`Offset: ${file.offset}`, `Size: ${file.size}`] }); } // Create artifact artifacts.push({ id: crypto.randomUUID(), name: `carved_${file.offset}.${file.type}`, type: types_1.ArtifactType.OTHER, size: file.size, hash: file.hash || crypto.randomUUID(), extractedFrom: `offset_${file.offset}`, extractedAt: new Date(), metadata: { carved: true, header: file.header, footer: file.footer } }); } } return { findings, artifacts }; } async analyzeRegistry(registry) { const findings = []; const iocs = []; // Analyze autorun entries for (const autorun of registry.autorunEntries) { if (autorun.suspicious) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.PERSISTENCE, title: 'Suspicious Autorun Entry', description: `Suspicious persistence mechanism found in registry`, evidence: [`${autorun.location}\\${autorun.name}`, autorun.value], metadata: { autorun } }); // Extract file path as IOC const filePath = this.extractFilePathFromRegistry(autorun.value); if (filePath) { iocs.push({ type: types_1.IOCType.FILE_PATH, value: filePath, context: 'Registry autorun', confidence: 85 }); } } } // Check USB devices const recentUSB = registry.usbDevices.filter(usb => usb.lastConnected && usb.lastConnected > new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)); if (recentUSB.length > 0) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.INFO, type: types_1.FindingType.OTHER, title: 'Recent USB Device Usage', description: `${recentUSB.length} USB devices connected in last 7 days`, evidence: recentUSB.map(usb => `${usb.vendorId}:${usb.productId} (${usb.volumeName || 'Unknown'})`) }); } return { findings, iocs }; } async analyzeBrowserArtifacts(artifacts) { const findings = []; const iocs = []; // Group by browser and type const downloads = artifacts.filter(a => a.type === 'DOWNLOAD'); const suspiciousDownloads = downloads.filter(d => this.isSuspiciousDownload(d.url || '')); if (suspiciousDownloads.length > 0) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.SUSPICIOUS_PROCESS, title: 'Suspicious Downloads Detected', description: `Found ${suspiciousDownloads.length} suspicious downloads`, evidence: suspiciousDownloads.slice(0, 5).map(d => d.url || 'Unknown') }); // Add download URLs as IOCs for (const download of suspiciousDownloads) { if (download.url) { iocs.push({ type: types_1.IOCType.URL, value: download.url, context: `Downloaded via ${download.browser}`, firstSeen: download.timestamp, confidence: 80 }); } } } // Check for data exfiltration patterns const uploads = artifacts.filter(a => a.type === 'HISTORY' && a.url && (a.url.includes('upload') || a.url.includes('pastebin') || a.url.includes('mega.nz'))); if (uploads.length > 10) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.DATA_EXFILTRATION, title: 'Potential Data Exfiltration', description: 'Multiple uploads to file sharing services detected', evidence: uploads.slice(0, 5).map(u => u.url || 'Unknown') }); } return { findings, iocs }; } async analyzePrefetch(prefetchFiles) { const findings = []; // Look for suspicious executables for (const pf of prefetchFiles) { const filename = path.basename(pf.name, '.pf'); if (this.suspiciousFiles.has(filename)) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.HIGH, type: types_1.FindingType.SUSPICIOUS_PROCESS, title: `Suspicious Program Execution: ${filename}`, description: `Known malicious tool was executed ${pf.runCount} times`, evidence: [ `Last run: ${pf.lastRun.toISOString()}`, `Run count: ${pf.runCount}`, `Path: ${pf.path}` ], timestamp: pf.lastRun }); } // Check for renamed executables if (this.isRenamedExecutable(pf)) { findings.push({ id: crypto.randomUUID(), severity: types_1.FindingSeverity.MEDIUM, type: types_1.FindingType.SUSPICIOUS_PROCESS, title: 'Potentially Renamed Executable', description: `Executable ${filename} may be masquerading`, evidence: [`Loaded DLLs don't match expected profile`] }); } } return { findings }; } isSuspiciousPath(filepath) { const suspiciousPaths = [ '\\Temp\\', '\\TMP\\', '\\AppData\\Local\\Temp\\', '\\Users\\Public\\', '\\ProgramData\\', '\\Windows\\Temp\\' ]; return suspiciousPaths.some(p => filepath.includes(p)); } isSuspiciousDownload(url) { const suspiciousDomains = [ 'mega.nz', 'mediafire.com', 'anonfiles.com', 'sendspace.com', 'zippyshare.com' ]; const suspiciousExtensions = [ '.exe', '.scr', '.vbs', '.ps1', '.bat', '.cmd' ]; return suspiciousDomains.some(d => url.includes(d)) || suspiciousExtensions.some(e => url.endsWith(e)); } getArtifactType(filepath) { const ext = path.extname(filepath).toLowerCase(); switch (ext) { case '.exe': case '.dll': case '.sys': return types_1.ArtifactType.EXECUTABLE; case '.doc': case '.docx': case '.pdf': case '.xls': case '.xlsx': return types_1.ArtifactType.DOCUMENT; case '.ps1': case '.vbs': case '.js': case '.bat': case '.cmd': return types_1.ArtifactType.SCRIPT; case '.log': case '.evt': case '.evtx': return types_1.ArtifactType.LOG_FILE; default: return types_1.ArtifactType.OTHER; } } extractFilePathFromRegistry(value) { // Extract file paths from registry values const pathMatch = value.match(/[A-Z]:\\[^"]+/i); return pathMatch ? pathMatch[0] : null; } isRenamedExecutable(pf) { // Check if loaded DLLs match expected profile const commonSystemDlls = ['kernel32.dll', 'ntdll.dll', 'user32.dll']; const hasCommonDlls = pf.loadedDlls?.some(dll => commonSystemDlls.includes(path.basename(dll).toLowerCase())); // Suspicious if it loads system DLLs but has unusual name return hasCommonDlls && !this.knownGoodProcesses.has(path.basename(pf.name, '.pf')); } generateConclusion(findings) { const criticalCount = findings.filter(f => f.severity === types_1.FindingSeverity.CRITICAL).length; const highCount = findings.filter(f => f.severity === types_1.FindingSeverity.HIGH).length; const malwareCount = findings.filter(f => f.type === types_1.FindingType.MALWARE).length; const deletedCount = findings.filter(f => f.type === types_1.FindingType.DELETED_FILE).length; if (criticalCount > 0 || malwareCount > 0) { return `Critical evidence of compromise found. Discovered ${malwareCount} malware artifacts and ${deletedCount} deleted suspicious files. The system shows clear signs of malicious activity requiring immediate remediation.`; } else if (highCount > 0) { return `Suspicious activity detected on the system. Found ${highCount} high-severity findings including ${deletedCount} deleted files. Further investigation recommended to determine the extent of potential compromise.`; } else { return `Disk analysis complete. Found ${findings.length} findings requiring review. No definitive evidence of compromise, but recommend implementing security hardening measures.`; } } formatBytes(bytes) { const units = ['B', 'KB', 'MB', 'GB', 'TB']; let size = bytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return `${size.toFixed(2)} ${units[unitIndex]}`; } exportTimeline(analysis) { const lines = ['Timestamp,Action,Source,Actor,Target,Details']; for (const event of analysis.timeline || []) { lines.push([ event.timestamp.toISOString(), `"${event.action}"`, event.source, event.actor || '', `"${event.target || ''}"`, `"${event.details || ''}"` ].join(',')); } return Buffer.from(lines.join('\n')); } exportForensicXML(analysis) { // DFXML format const xml = `<?xml version="1.0" encoding="UTF-8"?> <dfxml version="1.0"> <metadata> <dc:type>Disk Analysis</dc:type> <dc:date>${analysis.timestamp.toISOString()}</dc:date> </metadata> <creator> <program>IOTA Disk Forensics</program> <version>1.0</version> </creator> <findings> ${analysis.findings.map(f => ` <finding> <severity>${f.severity}</severity> <type>${f.type}</type> <title>${this.escapeXML(f.title)}</title> <description>${this.escapeXML(f.description)}</description> </finding>`).join('')} </findings> <artifacts> ${analysis.artifacts.map(a => ` <artifact> <filename>${this.escapeXML(a.name)}</filename> <filesize>${a.size}</filesize> <hashdigest type="SHA-256">${a.hash}</hashdigest> </artifact>`).join('')} </artifacts> </dfxml>`; return Buffer.from(xml); } escapeXML(str) { return str .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;'); } async readHeader(path) { // Mock implementation return 'E01'; // EnCase format } async extractDeletedFiles(evidence) { // Mock implementation return []; } async extractRegistryHives(evidence) { // Mock implementation return []; } async extractBrowserData(evidence) { // Mock implementation return []; } async extractLogFiles(evidence) { // Mock implementation return []; } // Mock data generators generateMockTimeline() { const now = new Date(); const activities = []; // Generate timeline for last 7 days for (let i = 0; i < 1000; i++) { const timestamp = new Date(now.getTime() - Math.random() * 7 * 24 * 60 * 60 * 1000); const actions = ['CREATED', 'MODIFIED', 'ACCESSED', 'DELETED']; activities.push({ timestamp, action: actions[Math.floor(Math.random() * actions.length)], path: this.generateRandomPath(), size: Math.floor(Math.random() * 10 * 1024 * 1024), user: Math.random() > 0.5 ? 'DESKTOP-ABC\\user' : 'NT AUTHORITY\\SYSTEM', process: Math.random() > 0.7 ? 'explorer.exe' : undefined }); } // Add some suspicious activities activities.push({ timestamp: new Date(now.getTime() - 2 * 60 * 60 * 1000), action: 'CREATED', path: 'C:\\Windows\\Temp\\mimikatz.exe', size: 1234567, user: 'DESKTOP-ABC\\user' }); activities.push({ timestamp: new Date(now.getTime() - 1 * 60 * 60 * 1000), action: 'DELETED', path: 'C:\\Windows\\Temp\\mimikatz.exe', user: 'DESKTOP-ABC\\user' }); return activities.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); } generateMockDeletedFiles() { return [ { path: 'C:\\Users\\user\\Documents\\passwords.txt', deletedAt: new Date(Date.now() - 24 * 60 * 60 * 1000), size: 2048, recoverable: true, recovered: true, hash: 'abc123def456789012345678901234567890abcd', metadata: { fileType: 'text', createdAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) } }, { path: 'C:\\Windows\\Temp\\nc.exe', deletedAt: new Date(Date.now() - 2 * 60 * 60 * 1000), size: 59392, recoverable: true, recovered: true, hash: '8F26BA3F4D8E4A3B9F8E7D6C5B4A3928', metadata: { fileType: 'executable' } }, { path: 'C:\\Users\\user\\Downloads\\invoice_2024.exe', deletedAt: new Date(Date.now() - 12 * 60 * 60 * 1000), size: 512000, recoverable: false, recovered: false, metadata: { fileType: 'executable', suspicious: true } } ]; } generateMockCarvedFiles() { return [ { type: 'executable', offset: 0x1000000, size: 102400, recovered: true, hash: 'deadbeef00112233445566778899aabb', header: '4D5A', // MZ header footer: undefined }, { type: 'document', offset: 0x2000000, size: 204800, recovered: true, hash: 'cafebabe00112233445566778899aabb', header: '504B0304', // ZIP/DOCX header footer: '504B0506' } ]; } generateMockRegistry() { return { lastWriteTime: new Date(Date.now() - 60 * 60 * 1000), users: ['Administrator', 'user', 'Guest'], autorunEntries: [ { location: 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', name: 'SecurityUpdate', value: 'C:\\Windows\\Temp\\update.exe', user: 'SYSTEM', suspicious: true }, { location: 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', name: 'OneDrive', value: '"C:\\Program Files\\Microsoft OneDrive\\OneDrive.exe" /background', user: 'user', suspicious: false } ], recentDocs: [ 'budget_2024.xlsx', 'passwords.txt', 'confidential_report.pdf' ], installedPrograms: [ 'Microsoft Office', 'Google Chrome', 'TeamViewer', 'AnyDesk' ], networkShares: [ '\\\\fileserver\\public', '\\\\192.168.1.100\\share' ], usbDevices: [ { serialNumber: 'ABC123DEF456', vendorId: '0781', productId: '5567', firstConnected: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), lastConnected: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000), volumeName: 'SANDISK' } ] }; } generateMockBrowserArtifacts() { return [ { browser: 'Chrome', type: 'DOWNLOAD', url: 'https://mega.nz/file/abc123', title: 'tools.zip', timestamp: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), user: 'user' }, { browser: 'Chrome', type: 'HISTORY', url: 'https://pastebin.com/raw/xyz789', title: 'Pastebin - Raw', timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000), user: 'user' }, { browser: 'Firefox', type: 'DOWNLOAD', url: 'https://example.com/malware.exe', title: 'invoice.exe', timestamp: new Date(Date.now() - 24 * 60 * 60 * 1000), user: 'user' } ]; } generateMockPrefetch() { return [ { name: 'MIMIKATZ.EXE-1234ABCD.pf', path: 'C:\\Windows\\Temp\\mimikatz.exe', runCount: 3, lastRun: new Date(Date.now() - 2 * 60 * 60 * 1000), previousRuns: [ new Date(Date.now() - 24 * 60 * 60 * 1000), new Date(Date.now() - 12 * 60 * 60 * 1000) ], loadedDlls: ['kernel32.dll', 'ntdll.dll', 'advapi32.dll'] }, { name: 'POWERSHELL.EXE-5678EFGH.pf', path: 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', runCount: 156, lastRun: new Date(Date.now() - 30 * 60 * 1000), loadedDlls: ['kernel32.dll', 'ntdll.dll', 'mscoree.dll'] } ]; } generateRandomPath() { const dirs = [ 'C:\\Windows\\System32', 'C:\\Program Files', 'C:\\Users\\user\\Documents', 'C:\\Users\\user\\Downloads', 'C:\\Windows\\Temp', 'C:\\ProgramData' ]; const files = [ 'document.docx', 'image.jpg', 'data.xlsx', 'report.pdf', 'config.xml', 'log.txt' ]; return `${dirs[Math.floor(Math.random() * dirs.length)]}\\${files[Math.floor(Math.random() * files.length)]}`; } } exports.DiskAnalyzer = DiskAnalyzer; //# sourceMappingURL=disk-analyzer.js.map