savon-noir / python-libnmap

libnmap is a python library to run nmap scans, parse and diff scan results. It supports python 2.7 up to 3.8. It's wonderful.
https://libnmap.readthedocs.org
Other
489 stars 182 forks source link

libnmap.objects.NmapService.service returns value for name key and not the service dictionary #37

Closed manweile closed 9 years ago

manweile commented 10 years ago

NMap scan: nmap -sC -sV -T4 -O -v -iL K:\Development\Python\test_switches.txt -oX K:\Development\Python\test_switches.xml"

the xml produced: <?xml version="1.0"?> <!DOCTYPE nmaprun PUBLIC "-//IDN nmap.org//DTD Nmap XML 1.04//EN" "https://svn.nmap.org/nmap/docs/nmap.dtd"> <?xml-stylesheet href="file:///C:/Program Files/Nmap/nmap.xsl" type="text/xsl"?>

cpe:/a:ehttp:ehttp:2.0cpe:/h:hp:procurve_switch_2824cpe:/o:hp:procurve_switch_software cpe:/h:xerox:workcentre_pro_7245 cpe:/h:rockwellautomation:1769-l23e-qb1 cpe:/h:nortel:ethernet_routing_switch_5530 cpe:/h:netgear:wgt624 cpe:/h:hp:procurve_switch_2510 cpe:/h:hp:procurve_switch_2650 cpe:/o:windriver:vxworks cpe:/h:cisco:small_business_ip_phone:spa505g
cpe:/a:ehttp:ehttp:1.1cpe:/h:hp:procurve_switch_4000mcpe:/o:hp:procurve_switch_software cpe:/h:hp:procurve_switch_4000m cpe:/h:hp:procurve_switch_2424m cpe:/h:hp:procurve_switch_4000m cpe:/h:hp:brocade_1600 cpe:/o:ibm:os2:4
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6 cpe:/o:apple:iphone_os:2
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6 cpe:/o:apple:iphone_os:2
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6 cpe:/o:apple:iphone_os:2
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6 cpe:/o:apple:iphone_os:2
cpe:/a:ehttp:ehttp:1.1cpe:/h:hp:procurve_switch_4000mcpe:/o:hp:procurve_switch_software cpe:/h:hp:procurve_switch_4000m cpe:/h:hp:brocade_1600 cpe:/o:sonicwall:tz_170
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/h:hp:laserjet_m1522nf cpe:/o:ibm:i5os:v6
cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:freebsd:freebsd:6.2 cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:switch_e3500ylcpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6 cpe:/o:apple:iphone_os:2
cpe:/h:cisco:sg300-28p cpe:/h:cisco:catalyst_2950cpe:/h:cisco:catalyst_2960cpe:/h:cisco:catalyst_3550cpe:/h:cisco:catalyst_3560cpe:/h:cisco:catalyst_3750cpe:/o:cisco:ios:12
cpe:/a:openbsd:openssh:3.7.1p2 cpe:/a:ehttp:ehttp:2.0cpe:/h:hp:procurve_switch_2910al-24g-poecpe:/o:hp:procurve_switch_software cpe:/o:freebsd:freebsd:6.2 cpe:/h:hp:procurve_switch_5406zl cpe:/h:hp:procurve_switch_5412zl cpe:/o:juniper:junos:9 cpe:/o:m0n0wall:freebsd cpe:/o:apple:iphone_os:2 cpe:/o:freebsd:freebsd:6.3 cpe:/h:hp:procurve_switch_2910al cpe:/h:hp:laserjet_cp2025dn cpe:/o:ibm:i5os:v6

The code:

!/usr/bin/env python

import nmap library

from libnmap.parser import NmapParser from libnmap.objects import *

TODO check for valid input file name and valid csv export pathname

TODO use command line input for xml source file name

parse nmap xml and get nmap report object

nmapReport = NmapParser.parsefromfile('HO-sC-sV-T4-O-oX.xml')

nmapReport = NmapParser.parse_fromfile('test_120.xml')

nmapReport = NmapParser.parsefromfile('test-sC-sV-T4-O-oX-iL.xml')

nmapReport = NmapParser.parse_fromfile('test_printers.xml')

nmapReport = NmapParser.parse_fromfile('test_switches.xml')

TODO use command line input for output file

outputCsv = open('test_HO.csv', 'w')

write header line to console and csv

print('IP Address,State,Host Name,MAC Address,MAC Vendor,Device Type,OS') outputCsv.write('IP Address, State, Host Name, MAC Address, MAC Vendor, Device Type, OS\n')

get array of nmap host objects from nmap report object

hostList = nmapReport.hosts

iterate thru nmap host objects

for host in hostList:

will always have host IPv4 address and up/down status

hostAddy = host.address
hostStatus = host.status
#instantiate the other datums variables we are interested in
hostName = ""
hostMac = ""
hostVendor = ""
hostDevice = ""
hostOS = ""
#check if host is up
if host.is_up():
    #instantiate script result dictionaries
    nbstatDict = None
    smbDict = None
    #iterate thru array of script results dictionaries
    for scriptDict in host.scripts_results:
        #check for nbstat scriptname id
        if scriptDict.get('id') == "nbstat":
            #get the nbstat script result dictionary
            nbstatDict = scriptDict
        #check for sm-os-discovery script id
        elif scriptDict.get('id') == "smb-os-discovery":
            smbDict = scriptDict

    #if we have an nbstat script results
    if nbstatDict:
        #get the hostname from it
        hostName = nbstatDict.get('elements').get('server_name')
    else:
        #check if we have a hostname from dns
        if len(host.hostnames) >0:
            #use the 1st fqdn hostname from array
            hostName = host.hostnames[0]
        else:
            #use the ipv4 addy
            hostName = host.address

    #if we have smb os discovery results 
    if smbDict:
        #get the os from it
        hostOS =  smbDict.get('elements').get('os')
    else:
        #check if we have a fingerprint
        if host.os_fingerprinted:
            #use the 1st (highest confidence) fingerprint
            hostOS = host.os.osmatches[0].name
        else:
            #use host ipv4 addy
            hostOS = "unable to determine OS"

    #get mac address
    hostMac = host.mac
    #get mac vendor
    hostVendor = host._address[1].get('vendor')

    #iterate thru list of NMap service objects for the current host
    for hostService in host.services:
        #get the services dictionary for current host 
        serviceDict = hostService.service
        #check for a printer
        if serviceDict.get('name') == "printer":
            hostDevice = "printer"
        #check for a switch
        if serviceDict.get('devicetype') == "switch":
            hostDevice = "switch"

#print the host info to console and csv
print(hostAddy, hostStatus, hostName, hostMac, hostVendor, hostDevice, hostOS, sep=",")
outputCsv.write(hostName + "," + hostStatus + "," + hostMac + "," + hostVendor + "," + hostDevice + "," + hostOS)

The results: pydev debugger: starting (pid: 2588) IP Address,State,Host Name,MAC Address,MAC Vendor,Device Type,OS Traceback (most recent call last): File "C:\Development\adt-bundle-windows-x86_64-20131030\eclipse\dropins\PyDev 3.5.0\plugins\org.python.pydev_3.5.0.201405201709\pysrc\pydevd.py", line 1845, in debugger.run(setup['file'], None, None) File "C:\Development\adt-bundle-windows-x86_64-20131030\eclipse\dropins\PyDev 3.5.0\plugins\org.python.pydev_3.5.0.201405201709\pysrc\pydevd.py", line 1373, in run pydev_imports.execfile(file, globals, locals) # execute the script File "C:\Development\adt-bundle-windows-x86_64-20131030\eclipse\dropins\PyDev 3.5.0\plugins\org.python.pydev_3.5.0.201405201709\pysrc_pydev_execfile.py", line 38, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) #execute the script File "K:\Development\Python\NMapParser.py", line 89, in if serviceDict.get('name') == "printer": AttributeError: 'str' object has no attribute 'get'

Now when I directly access the the service dictionary by changing line 87 to serviceDict = hostService._service from serviceDict = hostService.service, the proper results: IP Address,State,Host Name,MAC Address,MAC Vendor,Device Type,OS 129.129.10.24,up,129.129.10.24,00:0E:7F:C4:4D:C0,Hewlett-Packard Company,switch,Xerox WorkCentre Pro 7245 printer 129.129.10.25,up,129.129.10.25,00:10:83:0E:57:00,Hewlett-packard Company,switch,HP ProCurve 4000M switch (J4121A) 129.129.10.71,up,129.129.10.71,C0:91:34:C8:C0:80,ProCurve Networking by HP,switch,HP ProCurve 5406zl switch 129.129.10.72,up,129.129.10.72,68:B5:99:17:CD:C0,Hewlett-Packard Company,switch,HP ProCurve 5406zl switch 129.129.10.74,up,129.129.10.74,38:EA:A7:76:7C:C0,Hewlett Packard,switch,HP ProCurve 5406zl switch 129.129.10.76,up,129.129.10.76,C0:91:34:C4:D6:00,ProCurve Networking by HP,switch,HP ProCurve 5406zl switch 129.129.10.77,up,129.129.10.77,00:30:C1:22:B6:80,Hewlett-packard,switch,HP ProCurve 4000M switch (J4121A) 129.129.10.78,up,129.129.10.78,C0:91:34:C8:01:00,ProCurve Networking by HP,switch,HP ProCurve 5406zl switch 129.129.10.79,up,129.129.10.79,C0:91:34:C8:E1:00,ProCurve Networking by HP,switch,HP ProCurve 5406zl switch 129.129.10.85,up,129.129.10.85,F8:B1:56:0C:2C:12,Dell,switch,AVtech Room Alert 26W environmental monitor 129.129.10.158,up,edm-f0gggk1-mamilla.mwfp.mw,74:46:A0:57:21:00,Hewlett Packard,switch,FreeBSD 6.2-RELEASE

this looks like a similiar issue to issue 14.

savon-noir commented 10 years ago

could you send me xml + .py at mini.pelle@gmail.com ?

savon-noir commented 10 years ago

hello,

there is an error in the doc. NmapService.service returns the service name (what you try to get with serviceDict.get('name').

If you want to access the full dict, try the "protected" attribute NmapService._service.

In next version, i'll probably add a accessor for the _service and update the doc. It will be much cleaner.

I'll leave this open and flag it as "enhancement".

Thanks for reporting.

savon-noir commented 9 years ago

fixed in commit https://github.com/savon-noir/python-libnmap/commit/e64dd8aa416a169586f8d4b7792ff744fc74196f

added NmapService.service_dict accessor (property)