Initial commit
This commit is contained in:
21
server/package.json
Normal file
21
server/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "local-dashboard-backend",
|
||||
"version": "1.0.0",
|
||||
"description": "Backend service for the Local Network Dashboard to perform nmap scans.",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [
|
||||
"nmap",
|
||||
"network-scan",
|
||||
"dashboard"
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.19.2",
|
||||
"xml2js": "^0.6.2"
|
||||
}
|
||||
}
|
||||
92
server/server.js
Normal file
92
server/server.js
Normal file
@@ -0,0 +1,92 @@
|
||||
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}`);
|
||||
});
|
||||
Reference in New Issue
Block a user