3

I've been playing with the module straight from the python command line to try and figure out how it all works, and start to piece together how the script I want to write is going to need to work. What I'd like to do, is do a simple host discovery scan first, such as -n -sP -PE, then use the all_hosts() function to generate the host list for the actual port scan. So if I do...

import nmap
nm = nmap.PortScanner()

nm.scan(hosts='XXX.XXX.XXX.X/24', arguments='-n -sP -PE')

Then nm.all_hosts() gives me exactly what I'm looking for, a shortened list of all the active hosts that the scan found. Now, the problem I'm having is passing that into the next scan. If you just do something like

hostlist = nm.all_hosts()
nm.scan(hosts=hostlist etc)

Then it complains about not being able to use a list for the hosts argument. Ok, makes sense. So I tried to make it comma separted, so they'd show up as aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb etc, by doing...

hostlist = ""
for item in nm.all_hosts():
    hostlist = item + ", " + hostlist

Then, just dumping hostlist, it looks just how I'd like it to, but if you try to plug that into the hosts argument, it says "Failed to resolve "alltheipslisted" WARNING: No targets were specified, so 0 hosts scanned.

Does anyone have any good ideas for how to go about this? Maybe dumping the IPs to then pulling them from a file? Seems like I'd run into the same problem if a string isn't working...

Arvandor
  • 181
  • 1
  • 5
  • 15
  • My inner pedant wishes to point out that that is a terrible way of building a string, and will result in rapidly-increasing resource (CPU) exhaustion as nm.all_hosts() increases. Luckily, the accepted answer below uses string.join, which does not suffer from this algorithmic error. – bonsaiviking Jul 16 '14 at 17:22
  • Well, I'm pretty new to python, so let your inner pedant flow, I'm always willing to learn new tricks to increase efficiency. I've used .split, but .join is new to me, thanks =) – Arvandor Jul 16 '14 at 17:39
  • glad to help. It's a general problem, though, not Python-specific. Building long strings with concatenation is bad in Java, Lua, Ruby, and probably most other languages. Has to do with allocating and copying memory for the entire string every time you do a concatenation. – bonsaiviking Jul 17 '14 at 02:39

1 Answers1

3

If you remove the comma it will work. Multiple hosts are listed with only a space between them.

Example of use:

import nmap
nm = nmap.PortScanner()

hostlist = ' '.join(nm.all_hosts())
nm.scan(hosts=hostlist, arguments='-n -sP -PE')
dwitvliet
  • 7,242
  • 7
  • 36
  • 62
  • Well don't I feel a bit retarded... How could I have forgotten that? I never type the commas in when I'm doing the scan the hard way, don't know why I thought I needed them when writing python. Weird mental glitch, thanks Banana. – Arvandor Jul 16 '14 at 17:14
  • The next problem is that -PN doesn't seem to output properly in Python... It's not getting the actual results, only what appears to be the information for the scan it's attempting. Is there a different switch I can use that will allow me to see which ports are open on which hosts? – Arvandor Jul 16 '14 at 17:31
  • 1
    @Arvandor -PN means "Skip host discovery" so `-sP -PN` is a no-op ("do host discovery only, but skip host discovery and assume everything is up"). strangely, `-PE` overrides `-Pn`, but don't rely on that behavior: it is undefined and is likely to change, since I don't agree with it. – bonsaiviking Jul 17 '14 at 02:42
  • I wasn't doing -sP -PN though, just -PN, so the nm.command_line() looked something like "-oX - -PN." I did seem to get it working the way I wanted, for at least one run, and tried to dump the values into a MySQL database, which also worked, but maybe I should start a new thread for this new problem... Now that I think about it. – Arvandor Jul 17 '14 at 14:36