Pages

Thursday, January 9, 2014

Speeding up nmap with node.js

The tool; nmap

When it comes to network host discovery, enumerating details on remote hosts such operating system, device type and open ports nmap is the tool the majority of sys admins, hackers, pen testers & script kiddies turn to first.

I consider it a great piece of software, however I also find it painfully slow.

Performance

While nmap has many options for tuning the performance of a scan I thought it might be a worthy challenge to increase this. The current documentation has this to say about performance of nmap scans...

While Nmap utilizes parallelism and many advanced algorithms to accelerate these scans, the user has ultimate control over how Nmap runs.

Fair enough, lets see what we can do shall we?

node-libnmap

While far from a complete solution, the current version (v0.0.3) of node-libnmap dramatically speeds up scans.

It does this by creating equally distributed scan blocks based on the number of hosts per subnet range and the number of CPU cores on the machine. For example; the application generates a total set of blocks equal to 32 (8 core processor) for a machine residing on a network cidr of 10.0.2.0/24. Example:

nmap -sn -oG - 10.0.2.1-31
nmap -sn -oG - 10.0.2.33-63
nmap -sn -oG - 10.0.2.65-95
nmap -sn -oG - 10.0.2.97-127
nmap -sn -oG - 10.0.2.129-159
nmap -sn -oG - 10.0.2.161-191
nmap -sn -oG - 10.0.2.193-223
nmap -sn -oG - 10.0.2.225-255

The next step uses nodes thread model to create a new child process executing asynchronously (with the help of the async module) for every block generated.

benchmarks

Here are some preliminary benchmarks and samples

The results here are all coming from a virtual environment with limited system resources but should give an overall picture of performance of the scans. My VM environment is using 8 cores with 4 threads per core given a total returned from require('os').cpus.length = 32.

Nmap host discovery

$ time nmap -sn -oG - 10.0.2.0/24
# Nmap 5.51 scan initiated Wed Jan  8 18:54:07 2014 as: nmap -sn -oG - 10.0.2.0/24
Host: 10.0.2.2 ()       Status: Up
Host: 10.0.2.3 ()       Status: Up
Host: 10.0.2.15 ()      Status: Up
# Nmap done at Wed Jan  8 18:54:26 2014 -- 256 IP addresses (3 hosts up) scanned in 19.33 seconds

real    0m19.339s
user    0m0.052s
sys     0m0.080s

Nmap host discovery using node-libnmap

$ time node test/run.js 
{ adapter: 'eth0',
  properties: 
   { address: '10.0.2.15',
     netmask: '255.255.255.0',
     family: 'IPv4',
     mac: '52:54:00:12:34:56',
     internal: false,
     cidr: '10.0.2.0/24',
     hosts: 256,
     range: { start: '10.0.2.1', end: '10.0.2.254' } },
  neighbors: [ '10.0.2.2', '10.0.2.3', '10.0.2.15' ] }

real    0m3.323s
user    0m0.326s
sys     0m0.412s

And an example with multiple adapters on multiple 802.11q segments

$ time node test/run.js 
[ { adapter: 'eth0',
    properties: 
     { address: '10.0.2.15',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '52:54:00:12:34:56',
       internal: false,
       cidr: '10.0.2.0/24',
       hosts: 256,
       range: { start: '10.0.2.1', end: '10.0.2.254' } },
    neighbors: [ '10.0.2.2', '10.0.2.3', '10.0.2.15' ] },
  { adapter: 'eth1',
    properties: 
     { address: '192.168.2.15',
       netmask: '255.255.255.128',
       family: 'IPv4',
       mac: '52:54:00:12:34:57',
       internal: false,
       cidr: '192.168.2.0/25',
       hosts: 128,
       range: { start: '192.168.2.1', end: '192.168.2.254' } },
    neighbors: [ '192.168.2.2', '192.168.2.3', '192.168.2.15' ] } ]

real    0m3.447s
user    0m0.493s
sys     0m0.796s

Mileage may vary

No comments:

Post a Comment