const express = require('express'); const { exec } = require('child_process'); const xml2js = require('xml2js'); const cors = require('cors'); const os = require('os'); const { promisify } = require('util'); const execAsync = promisify(exec); const app = express(); const port = 3001; // Use CORS to allow requests from the frontend app.use(cors()); app.use(express.json()); // Basic validation for CIDR notation const isValidCIDR = (cidr) => { const cidrRegex = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))$/; return cidrRegex.test(cidr); }; app.post('/api/scan', async (req, res) => { const { network } = req.body; if (!network || !isValidCIDR(network)) { return res.status(400).json({ error: 'Invalid or missing network address in CIDR format (e.g., 192.168.1.0/24).' }); } // Sanitize input to prevent command injection // The regex validation is the primary defense here. const sanitizedNetwork = network; console.log(`[SCAN STARTED] for network: ${sanitizedNetwork}`); // Command to find hosts with a wide range of common web ports open and output as XML. // This is more efficient than scanning all 65535 ports. const command = `nmap -p 80,443,3000,5000,7878,8080,8443,9000,9090,9091,9443,10000,32400,8000-8999 --open ${sanitizedNetwork} -oX -`; try { const { stdout, stderr } = await execAsync(command, { timeout: 300000 }); // 5 minute timeout if (stderr) { console.error(`[NMAP STDERR] ${stderr}`); } const parser = new xml2js.Parser(); const result = await parser.parseStringPromise(stdout); const services = []; if (result.nmaprun && result.nmaprun.host) { result.nmaprun.host.forEach(host => { const address = host.address[0].$.addr; if (host.ports && host.ports[0].port) { host.ports[0].port.forEach(portInfo => { const port = portInfo.$.portid; let url; if (port === '443') { url = `https://${address}`; } else if (port === '80') { url = `http://${address}`; } else { url = `http://${address}:${port}`; } const serviceName = portInfo.service && portInfo.service[0].$.name ? portInfo.service[0].$.name.replace(/-http$/, '') // Clean up names like 'http-proxy' : `Web Service @ ${address}`; services.push({ name: `${serviceName.charAt(0).toUpperCase() + serviceName.slice(1)} (${port})`, url: url, description: `Discovered service on port ${port}.` }); }); } }); } console.log(`[SCAN COMPLETE] Found ${services.length} services on ${sanitizedNetwork}.`); res.json(services); } catch (error) { console.error(`[SCAN FAILED] Error executing nmap:`, error); res.status(500).json({ error: 'Failed to execute nmap scan. Is nmap installed and in your system PATH?' }); } }); app.listen(port, () => { console.log(`Backend server running on http://localhost:${port}`); });