UNPKG

network-mapper

Version:

Nmap wrapper for node fully coded in TypeScript.

269 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NmapScan = void 0; const child_process_1 = require("child_process"); const xml2js_1 = require("xml2js"); const MacFormatter_1 = require("../../helpers/MacFormatter"); class NmapScan { constructor(opts) { this.nmapLocation = 'nmap'; this.options = {}; this.arguments = []; if (opts) { this.options = opts; } } async run() { this.arguments = this.constructArguments(); const result = await this.exec(); this.rawResponse = await xml2js_1.parseStringPromise(result, { mergeAttrs: true, explicitArray: false }); this.response = {}; this.parse(); this.response.nmapArguments = this.rawResponse['nmaprun']['args']; return this.response; } constructArguments() { const opts = this.options; this.args = []; // Output to console in XML format this.args.push('-oX', '-'); // scanType switch (opts.scanType) { case 'list-scan': this.args.push('-sL'); break; case 'ping-scan': this.args.push('-sn'); break; case 'protocol-scan': this.args.push('-sO'); break; } // resolve switch (opts.resolve) { case 'never': this.args.push('-n'); break; case 'always': this.args.push('-R'); break; case 'all': this.args.push('--resolve-all'); break; } // randomizePorts if (opts.randomizePorts === false) { this.args.push('-r'); } // sendMechanism switch (opts.sendMechanism) { case 'ip': this.args.push('--send-ip'); break; case 'eth': this.args.push('--send-eth'); break; } // privilegedMode if (opts.privilegedMode !== undefined) { if (opts.privilegedMode) { this.args.push('--privileged'); } else { this.args.push('--unprivileged'); } } // data if (opts.data !== undefined) { if (typeof (opts.data) == 'string') { this.args.push('--data-string', `"${opts.data}"`); } else if (Buffer.isBuffer(opts.data)) { this.args.push('--data', opts.data.toString('hex')); } } // dryrun if (opts.dryrun && opts.scanType == 'list-scan') { this.args.push('-n'); } this.addSimpleArgument('-iR', opts.random); this.addArrayArgument('--exclude', opts.exclude); this.addArrayArgument('--dns-servers', opts.dnsServer); this.addSwitchArgument('--system-dns', opts.useSystemDns); this.addSwitchArgument('--traceroute', opts.traceroute); this.addSimpleArgument('--ttl', opts.ttl); this.addSimpleArgument('-e', opts.interface); this.addSimpleArgument('-S', opts.sourceIp); this.addSimpleArgument('--source-port', opts.sourcePort); this.addSwitchArgument('-f', opts.fragment); this.addSimpleArgument('--mtu', opts.mtu); this.addArrayArgument('-D', opts.decoy); this.addArrayArgument('--proxies', opts.proxy); this.addSimpleArgument('--spoof-mac', opts.sourceMac); this.addSwitchArgument('-F', opts.fastScan); this.addSwitchArgument('--randomize-hosts', opts.randomizeHosts); this.addSwitchArgument('--badsum', opts.badsum); this.addSwitchArgument('-6', opts.ipv6); this.addSimpleArgument('-T', opts.timing); this.addSimpleArgument('--min-hostgroup', opts.minHostgroup); this.addSimpleArgument('--max-hostgroup', opts.maxHostgroup); this.addSimpleArgument('--min-parallelism', opts.minParallelism); this.addSimpleArgument('--max-parallelism', opts.maxParallelism); this.addSimpleArgument('--min-rate', opts.minRate); this.addSimpleArgument('--max-rate', opts.maxRate); this.addSwitchArgument('--defeat-rst-ratelimit', opts.ignoreRstRateLimit); this.addSwitchArgument('--defeat-icmp-ratelimit', opts.ignoreIcmpRateLimit); this.addSwitchArgument('--disable-arp-ping', opts.disableArpPing); this.addSimpleArgument('--initial-rtt-timeout', opts.initialRttTimeout); this.addSimpleArgument('--min-rtt-timeout', opts.minRttTimeout); this.addSimpleArgument('--max-rtt-timeout', opts.maxRttTimeout); this.addSimpleArgument('--max-retries', opts.maxRetries); this.addSimpleArgument('--host-timeout', opts.hostTimeout); this.addSimpleArgument('--script-timeout', opts.scriptTimeout); this.addSimpleArgument('--scan-delay', opts.scanDelay); this.addSimpleArgument('--max-scan-delay', opts.maxScanDelay, `${opts.maxScanDelay}ms`); this.addSimpleArgument('--nsock-engine', opts.nsockEngine); this.addSwitchArgument('-Pn', opts.skipHostDiscovery); this.addArrayArgument('--exclude-ports', opts.excludePort); this.addArrayArgument('-p', opts.port); this.addSimpleArgument('--port-ratio', opts.portRatio); this.addSimpleArgument('--top-ports', opts.topPorts); this.addSimpleArgument('-iR', opts.random); // this.addArrayArgument(undefined, opts.target, ' ') if (opts.target !== undefined) { if (Array.isArray(opts.target)) { this.args = this.args.concat(opts.target); } else { this.args.push(opts.target); } } return this.args; } addSwitchArgument(label, value) { if (value === undefined || !value) return; this.args.push(label); } addSimpleArgument(label, value, formattedValue) { if (value === undefined) return; const representation = formattedValue !== undefined ? formattedValue : value; this.args.push(label, representation); } addArrayArgument(label, value) { if (value === undefined) return; if (label != undefined) { this.args.push(label); } this.args.push(Array.isArray(value) ? value.join(',') : value); } parse() { this.response.version = this.rawResponse['nmaprun']['version']; this.response.timestamp = new Date(this.rawResponse['nmaprun']['start'] * 1000); this.response.duration = this.rawResponse['nmaprun']['runstats']['finished']['elapsed'] * 1000; const run = this.rawResponse['nmaprun']; // hosts const hosts = Array.isArray(run['host']) ? run['host'] : [run['host']]; if (hosts) { this.response.hosts = []; hosts.forEach(host => { if (host === undefined) return; const responseHost = {}; // status const hostStatus = host['status']; if (hostStatus) { responseHost.state = hostStatus['state']; responseHost.reason = hostStatus['reason']; responseHost.ttl = Number(hostStatus['reason_ttl']); } // addresses const hostAddress = host['address']; if (hostAddress) { const hostAddresses = Array.isArray(hostAddress) ? hostAddress : [hostAddress]; hostAddresses.forEach(hostAddress => { if (hostAddress['addrtype'] === 'ipv4') { responseHost.ipAddress = hostAddress['addr']; } else if (hostAddress['addrtype'] === 'mac') { responseHost.mac = MacFormatter_1.formatMac(hostAddress['addr']); responseHost.vendor = hostAddress['vendor']; } }); } // hostname const hostnames = host['hostnames'] ? host['hostnames']['hostname'] : undefined; if (hostnames) { responseHost.hostnames = []; if (Array.isArray(hostnames)) { hostnames.forEach(host => { responseHost.hostnames.push(host['name']); }); } else { responseHost.hostnames.push(hostnames['name']); } } // hops if (host['trace']) { const trace = host['trace']['hop']; const hops = Array.isArray(trace) ? trace : [trace]; if (hops) { responseHost.hops = []; hops.forEach(hop => { responseHost.hops.push({ ttl: Number(hop['ttl']), ipAddress: hop['ipaddr'], rtt: Number(hop['rtt']), host: hop['host'] }); }); } } // ports const ports = host['ports']; if (ports) { const portArray = Array.isArray(ports['port']) ? ports['port'] : [ports['port']]; if (portArray) { responseHost.ports = []; portArray.forEach(port => { const openPort = { number: Number(port['portid']), protocol: port['protocol'], state: port['state']['state'], reason: port['state']['reason'], ttl: Number(port['state']['reason_ttl']) }; if (port['service'] !== undefined) openPort.service = port['service']['name']; responseHost.ports.push(openPort); }); } } this.response.hosts.push(responseHost); }); } } async exec() { let childOutput = ''; const child = await child_process_1.spawn(this.nmapLocation, this.arguments); child.stdout.on('data', (chunk) => { childOutput += chunk.toString(); }); return new Promise((resolve, reject) => { child.on('exit', (code) => { if (code != 0) { return reject(`Nmap child process has exited with code: ${code}`); } resolve(childOutput); }); }); } } exports.NmapScan = NmapScan; //# sourceMappingURL=NmapScan.js.map