Nmap isn't fundamentally flawed. It's ambitious and sprawling in ways that detract from its basic purpose. It wants to be a general-purpose network surveying tool, but is constrained to the UX of a port scanner.
Someone else should write the best possible port scanner and free nmap up to be the giant network profiling system it clearly wants to be.
"It wants to be a general-purpose network surveying tool, but is constrained to the UX of a port scanner."
What exactly does that mean? Nmap certainly isn't constrained to the UX of a port scanner. In fact, their expansion wasn't even in the form of bundled build, you can get all the tools separated, like: nmap, nping, ncat, ncrack...
So actually, it really isn't detracting from its basic purpose, you can still run simple network scans. But, if you got the knowledge, skills and the other tools installed, you can then also do much than advanced network scans, like vulnerability discovery and exploitation, passwords bruteforcing, etc...
Your comment isn't making much sense to me, please help me understand.
It has N different kinds of "stealth" scans that all produce the same kernel of valuable information, it has an elaborate (and, against most corporate networks from external vantage points, not particularly accurate or helpful) OS detection scheme, it runs scripts, it produces stdout and file output in a variety of complicated formats (it really just wants to be a service hooked up to a database), it runs scripts, IT RUNS SCRIPTS, come on. This isn't a serious argument. You just like nmap. That's fine; I think nmap is impressive too.
Oh, and it takes _for_ _ever_ to run. I'll pastie the 50 line EventMachine scripts I race it with when people on my team get stuck waiting for 12-hour nmap runs.
Sure. You know how simple this task is when you have an event loop, right? Here, I'll write a port scanner right now:
class HostProbe
module Probe
attr_accessor :bp
def connection_completed
@win = true
end
def unbind
self.bp.closed(self, @win)
end
end
def closed(obj, won)
@inflight_now -= 1
port = @inflight_q.delete(obj)
if won
puts "%TARGET-LISTENING: #{ @target }:#{ port }"
end
fill()
end
def sweep
Generator.new do |g|
(1..65535).each {|port| g.yield port}
end
end
def fill
@inflight_now.upto(@inflight_max) {
@inflight_now += 1
if(port = @sweep.next)
EventMachine::connect(@target, port, Probe) do |c|
c.bp = self
@inflight_q[c] = port
end
end
}
end
def initialize(host, opts={})
@target = host
@sweep = sweep
@inflight_q = {}
@inflight_now = 0
@inflight_max = opts[:inflight_max] || 10
fill()
end
end
EventMachine::run {
HostProbe.new(ARGV[0])
}
I think that may be it? I'm not even going to bother seeing if it evaluates. I write that stupid script once a month or so. There is probably a set of nmap options that crushes it for speed, but with the default options and a firewalled target network (ie: most professional nmap targets), I lap nmap with it.
Someone else should write the best possible port scanner and free nmap up to be the giant network profiling system it clearly wants to be.