#!/usr/bin/env python from xml.dom import minidom import sys class NMAPParser: def __init__(self, xmlfile=None): try: self._xmldoc = minidom.parse(xmlfile) except Exception, e: print '[-]', e.__class__, e self._xmldoc = None self._proto = None self._type = None self._hosts = {} self._parse() def _parse(self): # First let's check what type of scanning was used node = self._xmldoc.getElementsByTagName('scaninfo') if node: n = node[0] self._proto = n.getAttribute('protocol') if self._proto == 'tcp': self._type = n.getAttribute('type') else: self._type = None # Let's parse host informations. It works with dictionaries using # host[address] = {} subdictionaries, which hold information about # parsed data. nodes = self._xmldoc.getElementsByTagName('host') for node in nodes: n = node.getElementsByTagName('address')[0] if n: # Generate main subdictionary ip = n.getAttribute('addr') self._hosts[n.getAttribute('addr')] = {} else: ip = None if not ip: continue n = node.getElementsByTagName('status')[0] if n: self._hosts[ip]['status'] = n.getAttribute('state') else: self._hosts[ip]['status'] = None n = node.getElementsByTagName('port') while True: try: port = n.pop() except: break try: x = self._hosts[ip]['ports'] except: self._hosts[ip]['ports'] = {} p_num = port.getAttribute('portid') if not p_num: continue try: x = self._hosts[ip]['ports'][p_num] except: self._hosts[ip]['ports'][p_num] = {} try: state = port.getElementsByTagName('state')[0] self._hosts[ip]['ports'][p_num]['state'] = state.getAttribute('state') except Exception: continue try: service = port.getElementsByTagName('service')[0] self._hosts[ip]['ports'][p_num]['service'] = {} self._hosts[ip]['ports'][p_num]['service']['name'] = \ service.getAttribute('name') self._hosts[ip]['ports'][p_num]['service']['version'] = \ service.getAttribute('version') self._hosts[ip]['ports'][p_num]['service']['extra'] = \ service.getAttribute('extrainfo') except Exception, e: continue n = node.getElementsByTagName('osclass') if n: try: x = self._hosts[ip]['os_info'] except: x = self._hosts[ip]['os_info'] = {} osclass = n[0] family = osclass.getAttribute('osfamily') if family: self._hosts[ip]['os_info']['family'] = family else: self._hosts[ip]['os_info']['family'] = None osgen = osclass.getAttribute('osgen') if osgen: self._hosts[ip]['os_info']['version'] = osgen else: self._hosts[ip]['os_info']['version'] = None def getScanInfo(self): return (self._proto, self._type) def getHostsDict(self): return self._hosts def print_out(dict): if not dict: return None i = 0 x = 0 for host in dict.keys(): print '======================================' print '[%s] =>' % host print '\tstatus = %s' % dict[host]['status'] try: x = dict[host]['ports'] except: x = 0 if x: print '\tports =>' for port in dict[host]['ports'].keys(): print '\t\t[%d]' % int(port) print '\t\tstate = %s' % dict[host]['ports'][port]['state'] try: x = dict[host]['ports'][port]['service'] except: x = 0 if x: print '\t\tservice =>' print '\t\t\tservice_name = %s' % dict[host]['ports'][port]['service']['name'] print '\t\t\tservice_version = %s' % dict[host]['ports'][port]['service']['version'] print '\t\t\tservice_extra = %s' % dict[host]['ports'][port]['service']['extra'] try: x = dict[host]['os_info'] except: x = 0 if x: print '\tos info =>' print '\t\tos family = %s' % dict[host]['os_info']['family'] print '\t\tos version = %s' % dict[host]['os_info']['version'] def main(arg): if not arg: return None n = NMAPParser(arg) print '[+] Protocol: %s\tScan Type: %s' % n.getScanInfo() res = n.getHostsDict() print_out(res) if __name__ == '__main__': if len(sys.argv) < 2: print 'Usage: %s ' % sys.argv[0] sys.exit(0) main(sys.argv[1])