Index: zenmapCore/NmapParser.py =================================================================== --- zenmapCore/NmapParser.py (revision 32398) +++ zenmapCore/NmapParser.py (working copy) @@ -162,6 +162,7 @@ self._state = '' self._comment = '' self._trace = {} + self._hostscripts = [] def make_clone(self): clone = HostInfo() @@ -181,6 +182,7 @@ clone._state = self._state clone._comment = self._comment clone._trace = copy.deepcopy(self._trace) + clone._hostscripts = copy.deepcopy(self._hostscripts) return clone @@ -222,7 +224,7 @@ # 'osclasses': ...} # where each 'osclasses' element is a dict of the form # {'vendor': u'Linux', 'osfamily': u'Linux', 'type': u'general purpose', - # 'osgen': u'2.6.X', 'accuracy': u'98'} + # 'osgen': u'2.6.X', 'accuracy': u'98', 'cpe':'cpe:/o:linux:2.6'} def set_osmatches(self, matches): self._osmatches = matches @@ -275,6 +277,28 @@ def get_ports(self): return self._ports + # hostscripts is an array containing dicts of the form + # {'id': u'script-name', 'output': u'script-output'} + def set_hostscripts(self, hostscripts): + self._hostscripts = hostscripts + + def get_hostscripts(self): + return self._hostscripts + + """ + def get_hostscripts(self): + hostscripts = [] + for s in self._hostscripts: + hostscripts.append({ + 'id': s.get("id", ""), + 'output': s.get("output", ""), + }) + return hostscripts + + def set_hostscripts(self, hostscripts): + self._hostscripts = hostscripts + """ + # extraports is an array of dicts of the form # {'count': u'1709', 'state': u'filtered'} def set_extraports(self, port_list): @@ -447,6 +471,7 @@ comment = property(get_comment, set_comment) services = property(get_services) trace = property(get_trace, set_trace) + hostscripts = property(get_hostscripts, set_hostscripts) class ParserBasics(object): def __init__ (self): @@ -766,8 +791,14 @@ self.in_hostnames = False self.in_ports = False self.in_port = False + self.in_port_service = False + self.in_port_service_cpe = False + self.port_service_cpe = "" + self.in_portscript = False self.in_os = False + self.in_host_os_cpe = False self.in_trace = False + self.in_hostscript = False self.list_extraports = [] self.filename = None @@ -880,6 +911,12 @@ self.dic_port["service_version"] = attrs.get("version", "") self.dic_port["service_extrainfo"] = attrs.get("extrainfo", "") + def _parse_host_port_script(self, attrs): + self.port_scripts.append({ + "id": unique(attrs.get("id", "")), + "output": unique(attrs.get("output", "")) + }) + def _parse_host_osmatch(self, attrs): osmatch = self._parsing(attrs, [], ['name', 'accuracy', 'line']) osmatch['osclasses'] = [] @@ -927,6 +964,12 @@ def _parse_host_trace_error(self, attrs): self.host_info.set_trace_error(unique(attrs.get("errorstr", ""))) + def _parse_hostscripts(self, attrs): + self.dic_hostscript = { + "id": unique(attrs.get("id", "")), + "output": unique(attrs.get("output", "")) + } + def processingInstruction(self, target, data): if target == "xml-stylesheet": self.xml_stylesheet_data = data @@ -968,13 +1011,22 @@ self._parse_host_extraports(attrs) elif self.in_host and self.in_ports and name == "port": self.in_port = True + self.port_scripts = [] self._parse_host_port(attrs) elif self.in_host and self.in_ports and \ self.in_port and name == "state": self._parse_host_port_state(attrs) elif self.in_host and self.in_ports and \ self.in_port and name == "service": + self.in_port_service = True self._parse_host_port_service(attrs) + elif self.in_host and self.in_ports and self.in_port and \ + self.in_port_service and name == "cpe": + self.port_service_cpe = "" + self.in_port_service_cpe = True + elif self.in_host and self.in_ports and \ + self.in_port and name == "script": + self._parse_host_port_script(attrs) elif self.in_host and name == "os": self.in_os = True self.list_portused = [] @@ -986,6 +1038,9 @@ elif self.in_host and self.in_os and name == "osclass": self.list_osclass = [] self._parse_host_osclass(attrs) + elif self.in_host and self.in_os and name == "cpe": + self.host_os_cpe = '' + self.in_host_os_cpe = True elif self.in_host and name == "uptime": self._parse_host_uptime(attrs) elif self.in_host and name == "tcpsequence": @@ -1001,8 +1056,12 @@ self._parse_host_trace_hop(attrs) elif self.in_host and self.in_trace and name == "error": self._parse_host_trace_error(attrs) + elif self.in_host and name == "hostscript": + self.in_hostscript = True + self.list_hostscripts = [] + elif self.in_host and self.in_hostscript and name == "script": + self._parse_hostscripts(attrs) - def endElement(self, name): if name == "runstats": self.in_interactive_output = False @@ -1020,8 +1079,17 @@ self.in_ports = False elif self.in_host and self.in_ports and name == "port": self.in_port = False + self.in_port_service = False + self.in_port_service_cpe = False + self.dic_port["service_cpe"] = self.port_service_cpe + self.dic_port['scripts'] = self.port_scripts self.list_ports.append(self.dic_port) del(self.dic_port) + del(self.port_scripts) + self.port_service_cpe = "" + elif self.in_host and self.in_os and name == "cpe": + self.list_osclass[-1].update({'cpe': self.host_os_cpe}) + self.in_host_os_cpe = False elif self.in_host and self.in_os and name == "osmatch": self.list_osmatch[-1]['osclasses'].extend(self.list_osclass) self.list_osclass = [] @@ -1034,8 +1102,17 @@ del(self.list_osmatch) elif self.in_host and self.in_trace and name == "trace": self.in_trace = False + elif self.in_host and self.in_hostscript and name == "script": + self.list_hostscripts.append(self.dic_hostscript) + del(self.dic_hostscript) + elif self.in_host and self.in_hostscript and name == "hostscript": + self.in_hostscript = False def characters(self, content): + if self.in_host_os_cpe: + self.host_os_cpe += content + if self.in_port_service_cpe: + self.port_service_cpe += content if self.in_interactive_output: self.nmap_output += content @@ -1376,3 +1453,8 @@ for hop in host.trace["hops"]: print " ", repr(hop) print + if host.hostscripts: + print " Hostscripts:" + for s in host.hostscripts: + print "\t%s:" % repr(p.id) + print "\t\t".join(repr(p.output))