QtRecon includes a powerful XML parser to import Nmap scan results. The NmapParser class processes both Nmap and Masscan XML output.
utils/NmapParser.py
class NmapParser: def __init__(self, filename): with open(filename, 'r') as f: self.f = ''.join(f.readlines()) def parse_xml(self) -> dict: # Get online hosts hosts = dict() root = XMLparser.fromstring(re.sub(r'&#([a-zA-Z0-9]+);?', r'[#\1;]', self.f)) for host in root.iter('host'): if root.attrib['scanner'] == 'nmap' and host.find('status').attrib['state'] == 'down': continue ip = host.find('./address/[@addrtype="ipv4"]').attrib['addr']
The parser extracts comprehensive host information:
1
Host identification
IP address, MAC address, and hostname are extracted from the scan results.
2
OS fingerprinting
Operating system family is identified when available, defaulting to “unknown” if not detected.
3
Port enumeration
Open ports are cataloged by protocol (TCP/UDP) with service descriptions including product, version, and extra info.
utils/NmapParser.py
hosts[ip] = { 'ip': ip, 'hostname': hostname, 'mac': mac, 'os': os, 'ports': {'tcp': {}, 'udp': {}}}# Get open portsfor port in host.iter('port'): if port.find('state').attrib['state'] == 'open': service = port.find('./service') description = "" if service is not None: if 'product' in service.attrib.keys(): description = service.attrib['product'] else: description = service.attrib['name'] if 'version' in service.attrib.keys(): description += f" {service.attrib['version']}" if 'extrainfo' in service.attrib.keys(): description += f" ({service.attrib['extrainfo']})"
In addition to XML parsing, QtRecon can parse standard .nmap text output:
utils/NmapParser.py
def parse_nmap(self) -> dict: """ From a .nmap file, search data related to target, and return as string @return: dict """ blacklist = [ "Read data files from: ", "Please report any incorrect results at", "Nmap done at" ] string_parsing = "" for line in self.f.split('\n'): # Remove comments if line.startswith('#'): continue # Remove useless elements if any(unwanted_element in line for unwanted_element in blacklist): continue string_parsing += line + '\n'
This filters out comments and non-essential information, extracting only the scan results for each discovered host.