All pastes #998718 Raw Edit

Something

public text v1 · immutable
#998718 ·published 2008-04-26 20:55 UTC
rendered paste body
#!/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 <filename.xml>' % sys.argv[0]
    sys.exit(0)
  
  main(sys.argv[1])